SparkCore 知识点 (一)

SparkCore
基于内存的分布式计算框架
官网:http://spark.apache.org/
文档:http://spark.apache.org/docs/1.6.1/
官方博客:https://databricks.com/blog

====================================================
Spark编译
http://spark.apache.org/docs/1.6.1/building-spark.html
-1. 下载
http://archive.apache.org/dist/spark/spark-1.6.1/
http://archive.apache.org/dist/spark/spark-1.6.1/spark-1.6.1.tgz
-2. 将所需要的所有文件上传linux
-3. 开始编译(需要进行的信息参考ppt)
-4. apache hadoop依赖编译
./make-distribution.sh --tgz \
-Phadoop-2.4 \
-Dhadoop.version=2.5.0 \
-Pyarn \
-Phive -Phive-thriftserver
-5. cdh hadoop版本编译
./make-distribution.sh --tgz \
-Phadoop-2.4 \
-Dhadoop.version=2.5.0-cdh5.3.6 \
-Pyarn \
-Phive -Phive-thriftserver

=====================================================
将SPARK源码导入IDEA中
过程见ppt或者笔记中的图片
备注:所有的源码(包括不限于需要运行的代码)所放到的文件夹路径中不允许存在空格和中文。
备注:导入之前可以考虑将repository(Windows Linux开发环境依赖maven本地仓库).zip的内容解压到本地的maven仓库中
IDEA默认快捷键:
CTRL+N => 查找类,按两次表示查找依赖的类
CTRL+F12 => 在当前类中查找方法,按两次表示查找父类中的方法
ALTER + ENTER => 万能的快捷键,主要用于异常提示、导包、类型给定等(鼠标放到异常位置或者需要给定类型的变量后面)

==============================================
Spark应用的四种运行环境
-1、 local => 主要用于开发(IDEA中运行)和开发的测试(spark-shell运行)
-2、 standalone => 将spark应用运行在spark自带的资源管理器上
-3、 yarn => 将spark应用运行在yarn上
80%的公司选择将程序运行在yarn上
-4、 mesos => 将spark应用运行在mesos上
standalone、yarn、mesos均为集群资源管理器;mesos、standalone都是类似yarn的一种资源管理器。

===============================================
Spark on Local
环境搭建
-1. 解压编译好的压缩包或者软件工具文件夹中的压缩包
-2. 进入spark的根目录
cd /opt/cdh-5.3.6
ln -s spark-1.6.0-bin-2.5.0-cdh5.3.6/ spark
cd spark
-3. 修改配置信息(conf/spark-env.sh)
mv conf/spark-env.sh.template conf/spark-env.sh
JAVA_HOME=/opt/modules/java
SCALA_HOME=/opt/modules/scala
HADOOP_CONF_DIR=/opt/cdh-5.3.6/hadoop/etc/hadoop
SPARK_LOCAL_IP=hadoop-senior01.ibeifeng.com
注意:HADOOP_CONF_DIR参数的含义是指定spark连接的hadoop的相关配置信息所在的文件夹路径,当spark应用程序连接hadoop的时候,从会该路径下加载相关的配置信息 ===> 实质上就是将hdfs-site.xml、core-site.xml、yarn-site.xml配置文件添加到spark应用程序的classpath环境变量中 ===> 可以考虑不配置该参数,直接将配置文件放到${SPARK_HOME}/conf文件夹中
linux本地环境测试
-1. 启动hdfs的服务
-2. 运行run-example
bin/run-example SparkPi
bin/run-example SparkPi 100
-3. 官方文档测试
bin/spark-shell
17/10/17 11:56:09 INFO ui.SparkUI: Started SparkUI at http://192.168.187.146:4040
17/10/17 11:56:10 INFO repl.SparkILoop: Created spark context..
Spark context available as sc.
/beifeng/bc3108de-6f74-468d-b5e3-a8392e287103/_tmp_space.db
17/10/17 11:56:50 INFO repl.SparkILoop: Created sql context (with Hive support)..
SQL context available as sqlContext.

scala>
val textFile = sc.textFile("/README.md") ===> 使用fs.defaultFS指定的文件系统进行RDD数据读取
val textFile = sc.textFile("file:///opt/cdh-5.3.6/spark/README.md") ==> 明确指定读取本地磁盘的文件数据(本地磁盘该文件存在)
textFile.count()
textFile.first()
val linesWithSpark = textFile.filter(line => line.contains("Spark"))
linesWithSpark
textFile.map(line => line.split(" ").size).reduce((a, b) => if (a > b) a else b)
textFile: 默认形成RDD数据格式是:文件中的一行数据就是RDD中的一条记录
备注:textFile给定的文件路径,如果没有给定schema信息的情况下,默认使用fs.defaultFS作为默认的schema;当配置好HADOOP_CONF_DIR,默认的文件系统为HDFS文件系统; 也就是说如果没有配置HADOOP_CONF_DIR配置信息,那么使用本地磁盘作为默认的文件系统

SparkCore
=================================================
WordCount程序

val rdd = sc.textFile ("/input/wordCount.txt")
val result2=rdd. flatMap (line => line.split(" ") ). filter (word => word. nonEmpty ).map(word => ( word,1 )). reduceByKey ((a,b)=>a+b).map(t=> t.swap ). sortByKey (ascending=false).map(t=>t.swap).take(10). foreach (i=>println(i))

如果要保存,仅需要把最后take(10). foreach (i=>println(i))替换为以下
saveAsTextFile("/output/spark/core/wc")
-1. 将word.txt上传到hdfs上
-2. WordCount案例实现
sc.setLogLevel("ERROR") // 修改当前应用的日志级别

//1. 基于输入数据构建RDD; textFile API是读取HDFS上的文件形成RDD,其中第一个参数给定HDFS上的文件路径,第二个参数给定形成RDD的最少分区数量;默认分区数为2
val rdd = sc.textFile("/input/wordCount.txt")
// rdd: org.apache.spark.rdd.RDD[String] = /beifeng/spark/data/word.txt MapPartitionsRDD[9] at textFile at <console>:27

// 2. WordCount代码实现
val rdd0 = rdd.flatMap(line => line.split(" "))
val rdd1 = rdd0.filter(word => word.nonEmpty)
val rdd2 = rdd1.map(word => (word,1))
val rdd3 = rdd2.groupBy(t => t._1)
val resultRDD1 = rdd3.map(t => {
// rdd3中的数据类型是一个二元组,第一个元素是进行分组的数据, 也就是单词,第二个数据,分组后,相同数据的value形成的一个迭代器; value本身的数据类型是一个(String,Int)的二元组
val word = t._1
val iter = t._2
val sum = iter.map(tt => tt._2).sum
(word, sum)
})

val rdd4 = rdd2.groupByKey()
val resultRDD2 = rdd4.map(t => {
// rdd4中的数据类型是一个二元组,第一个元素是进行分组的数据, 也就是单词,第二个数据,分组后,相同数据的value形成的一个迭代器;value的原始数据类型是Int
val word = t._1
val iter = t._2
val sum = iter.sum
(word, sum)
})

// aggregateByKey和reduceByKey的性能比groupByKey的性能高,在实际的工作中,优先考虑前两个API;性能高的原因是:前两个API在进行shuffle之前会对每个分区的数据进行聚会的聚合操作,可以降低shuffle传输量 ==> 类似MapReduce的combiner的作用
val resultRDD3 = rdd2.reduceByKey((a,b) => a + b)

// 3. 将结果数据输出
// 输出到控制台
resultRDD3.collect.foreach(i => println(i))
resultRDD3.first
resultRDD3.take(10)
// 输出到HDFS文件中
resultRDD3.saveAsTextFile("/beifeng/spark/core/wc")

=======================================================
TopN的程序
含义:获取出现次数最多的前N个元素的值
resultRDD3.map(t => (t._2, t._1)).sortByKey(ascending = false).take(5).map(t => t.swap)
// 默认的排序器对于元组的数据来讲,是先对第一个元素进行比较,如果第一个相同,再比较第二个、第三个....
resultRDD3.map(_.swap).top(5).map(_.swap)
resultRDD3.top(5)(ord = new scala.math.Ordering[(String,Int)](){
override def compare(x: (String,Int), y: (String,Int)): Int = {
// 返回0表示相等,-1表示x<y(负数),1表示x>y(正数)
val tmp = x._2.compare(y._2)
if (tmp != 0) {
tmp
} else {
x._1.compare(y._1)
}
}
})

作业:
考虑一下如果现在想获取出现次数最少的3个元素的值(至少出现8次以上),怎么实现???
考虑一下如果N特别大,大到N条数据没法放到内存中,这种情况下,TopN如何实现???(一般N为百万、千万以上的时候,就相当于是这种情况)
==========================================================
Standalone
是一种类似Yarn的spark自带的资源管理框架
Yarn结构
ResourceManager
负责集群资源的管理
NodeManager
负责当前节点上的资源管理
资源:CPU+内存
CPU指的是逻辑CPU、内存也是逻辑内存
CPU是参数yarn.nodemanager.resource.cpu-vcores(默认为8)控制,默认情况下表示一个NodeManager管理8核的CPU
内存是参数yarn.nodemanager.resource.memory-mb(默认8192)控制,默认情况下表示一个NodeManger管理8g的内存
默认情况下,一个MapReduce的task(map task\reduce task)需要1核cpu+1g内存
Standalone结构
Master
负责管理集群的所有资源
Worker
负责当前进程的所有资源
资源:CPU和内存
Standalone的环境配置:
-1. 前提:spark的本地执行环境已经搭建好了
-2. 修改conf/spark-env.sh文件内容
SPARK_MASTER_IP=hadoop-senior01.ibeifeng.com
SPARK_MASTER_PORT=7070
SPARK_MASTER_WEBUI_PORT=8080
SPARK_WORKER_CORES=2 ## 给定当前的机器上的一个worker进程允许分配/管理的cpu核数
SPARK_WORKER_MEMORY=2g ## 给定当前机器上的一个worker进程允许分配/管理的内存大小
SPARK_WORKER_PORT=7071
SPARK_WORKER_WEBUI_PORT=8081
SPARK_WORKER_INSTANCES=2 ## 给定当前机器上允许存在多少个worker进程
-3. 配置worker机器列表(slave列表)
mv conf/slaves.template conf/slaves
一行一个主机名 比如:com.james
-4. 启动standalone的服务
sbin/start-master.sh
sbin/start-slaves.sh
sbin/start-slave.sh spark://hadoop-senior01.ibeifeng.com:7070
sbin/stop-all.sh ==> 关闭所有
或者: sbin/start-all.sh ==> 开启所有
Standalone的测试
--master MASTER_URL spark://host:port, mesos://host:port, yarn, or local. ==> 指定spark应用的运行环境
bin/spark-shell --master spark://com.james:7070
val rdd = sc.textFile("/input/wordCount.txt")
val rdd0 = rdd.flatMap(line => line.split(" "))
val rdd1 = rdd0.filter(word => word.nonEmpty)
val rdd2 = rdd1.map(word => (word,1))
val resultRDD3 = rdd2.reduceByKey((a,b) => a + b)
resultRDD3.collect.foreach(println)

Standalone分布式配置
-1. 所有机器之间的免密码登录完全做好了
-2. 将一台配置好的机器上的spark内存copy到其它机器上,并且修改spark-env.sh中对应的IP地址信息以及路径信息(eg: JAVA_HOME\SCALA_HOME....)
-3. 在master机器上修改slaves文件内容,将所有的worker机器ip地址添加到文件中,一行一个

Standalone Master HA配置
http://spark.apache.org/docs/1.6.1/spark-standalone.html#high-availability
-1. Single-Node Recovery with Local File System
基于文件的单节点master恢复机制
修改conf/spark-env.sh文件内容添加一个环境变量
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=FILESYSTEM -Dspark.deploy.recoveryDirectory=/tmp"
-2. Standby Masters with ZooKeeper
基于zk的active、standby模式的HA热备机制
修改conf/spark-env.sh文件内容添加一个环境变量
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop01:2181,hadoop02:2181,hadoop03:2181 -Dspark.deploy.zookeeper.dir=/spark"
==================================================
应用的监控
监控:集群资源使用情况(网络、cpu、内存、磁盘...) + 应用的执行情况
-1. 应用的监控是专门的运维人员负责的
-2. 一般通过软件/框架自带的web ui进行监控(直接看或者爬虫),eg:50070、8088、8080、19888......
-3. 通过大数据专门的运维工具进行监控,比如: CM、Ambari
-4. 通过调度工具(eg: oozie)来进行监控
-5. 可以考虑在linux上启动服务的时候,在supervisor上启动服务进程

=====================================================
Spark应用监控
http://spark.apache.org/docs/1.6.1/monitoring.html
-1. 针对正在运行的应用而言,可以通过应用的web ui来进行查看应用的执行情况
默认的端口号是4040,当端口号被占用的时候,端口号往上递增(eg: 4041、4042....),可以根据参数spark.ui.port来进行控制(这个页面属于driver进行管理);eg: http://<driver-node>:4040
-2. 针对运行完成的应用而言,可以通过spark的job history服务来进行查看

MapReduce Job History Server配置
-1. 在yarn-site.xml中开启日志聚集功能 ==> 将执行日志上传hdfs
-2. 在yarn-site.xml中配置日志上传到hdfs的路径
-3. 开启mr-jobhistory服务即可查看执行历史记录

Spark应用开启日志聚集功能配置(执行测试之前必须创建好hdfs上的文件夹)
-1. hdfs dfs -mkdir -p /spark/history
-2. mv conf/spark-defaults.conf.template conf/spark-defaults.conf
-3. vim conf/spark-defaults.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://hadoop-senior01.ibeifeng.com:8020/spark/history
备注:这个的eventLog dir不支持ha配置
测试
重启一个spark-shell

Spark Job History Server配置
vim conf/spark-env.sh
SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://hadoop-senior01.ibeifeng.com:8020/spark/history -Dspark.history.ui.port=18080"
启动服务即可
sbin/start-history-server.sh
关闭服务
sbin/stop-history-server.sh


Spark History Server Rest API
eg: http://<server-url>:18080/api/v1
http://com.james:18080/api/v1/applications
eg:
http://hadoop-senior01:18080/api/v1/applications
http://hadoop-senior01:18080/api/v1/applications/local-1508229258808/jobs
=========================================================
Spark应用的结构
一个Spark应用就是通过spark-submit脚本执行一次
Driver+Executors
Driver:负责job的调度、executor运行资源的申请、task执行监控/调度等工作;运行main方法并构建SparkContext的进程就叫做Driver进程;一个spark应用有且只有一个Driver进程
Executor:负责具体的Task运行,task以线程的形式运行在Executor中;一个Spark应用至少有一个executor进程
一个spark应用中包含多个job(>=0)
一个job可以包含多个stage(>0) ==> stage类似MapReduce中的MapStage和ReduceStage
一个stage中可以包含多个Task(>0)
Task是最小执行单位,是运行在executor中的具体的数据处理进程;
task的数量和RDD中的分区数量是一样的
MapReducer的结构
ApplicationMaster ==> 负责task的运行调度(包括:资源申请、task kill/重试/运行....)
MapTask+ReduceTask ===> 具体的代码执行

=======================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值