@R星校长
Spark 第三天【SparkCore内容】
主要内容
- Spark-Core中的术语
- RDD的宽窄依赖
- Spark Stage & Spark计算模式
- Spark资源调度和任务调度
- Spark补充算子
- Spark PV&UV 案例
- Spark-Submit提交参数
学习目标
第一节 术语与宽窄依赖
- 术语解释
- 窄依赖和宽依赖
RDD 之间有一系列的依赖关系,依赖关系又分为窄依赖和宽依赖。
窄依赖
父 RDD 和子 RDD partition 之间的关系是一对一的。或者父 RDD 一个 partition 只对应一个子 RDD 的 partition 情况下的父 RDD 和子 RDD partition 关系是多对一的。不会有 shuffle 的产生。
宽依赖
父 RDD 与子 RDD partition 之间的关系是一对多。会有 shuffle 的产生。
宽窄依赖图理解:
第二节 Stage 的计算模式
Spark 任务会根据 RDD 之间的依赖关系,形成一个 DAG 有向无环图,DAG 会提交给 DAGScheduler,DAGScheduler 会把 DAG 划分相互依赖的多个 stage,划分 stage 的依据就是 RDD 之间的宽窄依赖。遇到宽依赖就划分 stage , 每个 stage 包含一个或多个 task 任务。然后将这些 task 以 taskSet 的形式提交给 TaskScheduler 运行。stage 是由一组并行的 task 组成。
stage 切割规则:
切割规则:从后往前,遇到宽依赖就切割 stage。
stage 计算模式:
pipeline 管道计算模式 , pipeline 只是一种计算思想,模式。
问题:
- 数据一直在管道里面什么时候数据会落地?
1) 对 RDD 进行持久化。
2) shuffle write 的时候。 - Stage 的 task 并行度是由 stage 的最后一个 RDD 的分区数来决定的 。
- 如何改变 RDD 的分区数?
例如:reduceByKey(XXX,3),GroupByKey(4) - 测试验证 pipeline 计算模式
1. val conf = new SparkConf()
2. conf.setMaster("local").setAppName("pipeline");
3. val sc = new SparkContext(conf)
4. val rdd = sc.parallelize(Array(1,2,3,4))
5. val rdd1 = rdd.map { x => {
6. println("map--------"+x)
7. x
8. }}
9. val rdd2 = rdd1.filter { x => {
10. println("fliter********"+x)
11. true
12. } }
13. rdd2.collect()
14. sc.stop()
第三节 Spark 资源调度和任务调度
- Spark 资源调度和任务调度的流程:
启动集群后,Worker 节点会向 Master 节点汇报资源情况,Master 掌握了集群资源情况。当 Spark 提交一个 Application 后,根据 RDD 之间的依赖关系将 Application 形成一个 DAG 有向无环图。任务提交后,Spark 会在 Driver 端创建两个对象:DAGScheduler 和 TaskScheduler,DAGScheduler 是任务调度的高层调度器,是一个对象。DAGScheduler 的主要作用就是将 DAG 根据 RDD 之间的宽窄依赖关系划分为一个个的 Stage,然后将这些 Stage 以 TaskSet 的形式提交给 TaskScheduler(TaskScheduler 是任务调度的低层调度器,这里 TaskSet 其实就是一个集合,里面封装的就是一个个的 task 任务,也就是 stage 中的并行度 task 任务),TaskSchedule 会遍历 TaskSet 集合,拿到每个 task 后会将 task 发送到计算节点 Executor 中去执行(其实就是发送到 Executor 中的线程池 ThreadPool 去执行)。task 在 Executor 线程池中的运行情况会向 TaskScheduler 反馈,当 task 执行失败时,则由 TaskScheduler 负责重试,将 task 重新发送给 Executor 去执行,默认重试 3 次。如果重试 3 次依然失败,那么这个 task 所在的 stage 就失败了。stage 失败了则由 DAGScheduler 来负责重试,重新发送 TaskSet 到 TaskSchdeuler ,Stage 默认重试 4 次。如果重试 4 次以后依然失败,那么这个 job 就失败了。job 失败了,Application 就失败了。
TaskScheduler 不仅能重试失败的 task,还会重试 straggling(落后,缓慢)task(也就是执行速度比其他 task 慢太多的 task)。如果有运行缓慢的 task 那么 TaskScheduler 会启动一个新的 task 来与这个运行缓慢的 task 执行相同的处理逻辑。两个 task 哪个先执行完,就以哪个 task 的执行结果为准。这就是 Spark 的推测执行机制。在 Spark 中推测执行默认是关闭的。推测执行可以通过 spark.speculation 属性来配置。
注意:
a) 对于 ETL 类型要入数据库的业务要关闭推测执行机制,这样就不会有重复的数据入库。
b) 如果遇到数据倾斜的情况,开启推测执行则有可能导致一直会有task重新启动处理相同的逻辑,任务可能一直处于处理不完的状态。 - 图解 Spark 资源调度和任务调度的流程
- 粗粒度资源申请和细粒度资源申请
- 粗粒度资源申请(Spark)
在 Application 执行之前,将所有的资源申请完毕,当资源申请成功后,才会进行任务的调度,当所有的 task 执行完成后,才会释放这部分资源。
优点:在 Application 执行之前,所有的资源都申请完毕,每一个 task 直接使用资源就可以了,不需要 task 在执行前自己去申请资源,task 启动就快了,task 执行快了,stage 执行就快了,job 就快了,application 执行就快了。
缺点:直到最后一个 task 执行完成才会释放资源,集群的资源无法充分利用。 - 细粒度资源申请(MapReduce)
Application 执行之前不需要先去申请资源,而是直接执行,让 job 中的每一个 task 在执行前自己去申请资源,task 执行完成就释放资源。
优点:集群的资源可以充分利用。
缺点:task自己去申请资源,task 启动变慢,Application 的运行就相应的变慢了。
第四节 补充算子
- transformations 类算子
- mapPartitionWithIndex
类似于 mapPartitions , 除此之外还会携带分区的索引值。 - repartition
增加或减少分区。会产生 shuffle。(多个分区分到一个分区不会产生 shuffle) - coalesce
coalesce 常用来减少分区,第二个参数是减少分区的过程中是否产生 shuffle。
true 为产生 shuffle,false 不产生 shuffle。默认是 false。
如果 coalesce 设置的分区数比原来的 RDD 的分区数还多的话,第二个参数设置为 false 不会起作用,如果设置成 true,效果和 repartition 一样。即 repartition(numPartitions) = coalesce(numPartitions,true) - groupByKey
作用在 K,V 格式的 RDD 上。根据 Key 进行分组。作用在(K,V),返回(K,Iterable )。 - zip
将两个 RDD 中的元素(KV 格式/非 KV格式)变成一个 KV 格式的 RDD , 两个 RDD 的每个分区元素个数必须相同。 - zipWithIndex
该函数将 RDD 中的元素和这个元素在 RDD 中的索引号(从 0 开始)组合成(K,V)对。 - mapValues
针对 K,V 格式的 RDD , 该函数对 K,V 格式 RDD 中的 value 做操作,返回是 K,V 格式的 RDD.
- Action类算子
- countByKey
作用到 K,V 格式的 RDD 上,根据 Key 计数相同 Key 的数据集元素。 - countByValue
根据数据集每个元素相同的内容来计数。返回相同内容的元素对应的条数。
第五节 Spark PV&UV
PV 是网站分析的一个术语,用以衡量网站用户访问的网页的数量。对于广告主,PV 值可预期它可以带来多少广告收入。一般来说,PV 与来访者的数量成正比,但是 PV 并不直接决定页面的真实来访者数量,如同一个来访者通过不断的刷新页面,也可以制造出非常高的 PV。
- 什么是 PV 值
PV(page view)即页面浏览量或点击量,是衡量一个网站或网页用户访问量。具体的说,PV 值就是所有访问者在 24 小时(0 点到 24 点)内看了某个网站多少个页面或某个网页多少次。PV 是指页面刷新的次数,每一次页面刷新,就算做一次 PV 流量。
度量方法就是从浏览器发出一个对网络服务器的请求(Request),网络服务器接到这个请求后,会将该请求对应的一个网页(Page)发送给浏览器,从而产生了一个 PV。那么在这里只要是这个请求发送给了浏览器,无论这个页面是否完全打开(下载完成),那么都是应当计为 1 个 PV。 - 什么是UV值
UV(unique visitor)即独立访客数,指访问某个站点或点击某个网页的不同 IP 地址的人数。在同一天内,UV 只记录第一次进入网站的具有独立 IP 的访问者,在同一天内再次访问该网站则不计数。UV 提供了一定时间内不同观众数量的统计指标,而没有反应出网站的全面活动。
第六节 Spark-Submit 提交参数
Options:
- –master
MASTER_URL, 可以是spark://host:port, mesos://host:port, yarn, yarn-cluster,yarn-client, local
- –deploy-mode
DEPLOY_MODE, Driver 程序运行的地方,client 或者 cluster , 默认是 client。 - –class
CLASS_NAME, 主类名称,含包名 - –jars
逗号分隔的本地 JARS, Driver 和 executor 依赖的第三方jar包 - –files
用逗号隔开的文件列表,会放置在每个 executor 工作目录中 - –conf
spark 的配置属性 - –driver-memory
Driver 程序使用内存大小(例如:1000M,5G),默认1024M - –executor-memory
每个 executor 内存大小(如:1000M,2G),默认1G
Spark standalone with cluster deploy mode only:
- –driver-cores
Driver程序的使用core个数(默认为1),仅限于Spark standalone模式
Spark standalone or Mesos with cluster deploy mode only: - –supervise
失败后是否重启Driver,仅限于Spark alone或者Mesos模式
Spark standalone and Mesos only: - –total-executor-cores
executor使用的总核数,仅限于SparkStandalone、Spark on Mesos模式
Spark standalone and YARN only:
- –executor-cores
每个executor使用的core数,Spark on Yarn默认为1,standalone默认为worker上所有可用的core。
YARN-only:
- –driver-cores
driver使用的core,仅在cluster模式下,默认为1。 - –queue
QUEUE_NAME 指定资源队列的名称,默认:default - –num-executors
一共启动的executor数量,默认是2个。
本节作业
- 什么是Spark RDD的宽窄依赖?
- 解释Spark的计算模式?
- 描述Spark资源调度和任务调度流程?
- Spark补充算子代码敲一遍
- 熟记Spark-Submit提交任务的参数