Spark内核原理
一、依赖关系
Spark中RDD的高效与DAG图有着莫大的关系,在DAG调度中需要对计算过程划分stage,而划分依据就是RDD之间的依赖关系。针对不同的转换函数,RDD之间的依赖关系分类窄依赖(narrow dependency)和宽依赖(wide dependency, 也称 shuffle dependency).
1.宽依赖(有shuffle )
父RDD的一个分区会被子RDD的多个分区所依赖,子RDD分区通常对应所有的父RDD分区(O(n),与数据规模有关) 。 例如 GroupByKey,reduceByKey,join,sortByKey等操作
2.窄依赖(没有shuffle )
父RDD的一个分区只会被子RDD的一个分区所依赖(一分区对一分区)。 子RDD分区通常对应常数个父RDD分区(O(1),与数据规模无关)
3.相比于宽依赖,窄依赖对优化很有利 ,主要基于以下两点:
(1) 宽依赖往往对应着shuffle操作,需要在运行过程中将同一个父RDD的分区传入到不同的子RDD分区中,中间可能涉及多个节点之间的数据传输;而窄依赖的每个父RDD的分区只会传入到一个子RDD分区中,通常可以在一个节点内完成转换。
(2) 当RDD分区丢失时(某个节点故障),spark会对数据进行重算。
1) 对于窄依赖,由于父RDD的一个分区只对应一个子RDD分区,这样只需要重算和子RDD分区对应的父RDD分区即可,所以这个重算对数据的利用率是100%的;
2)对于宽依赖,重算的父RDD分区对应多个子RDD分区,这样实际上父RDD 中只有一部分的数据是被用于恢复这个丢失的子RDD分区的,另一部分对应子RDD的其它未丢失分区,这就造成了多余的计算;更一般的,宽依赖中子RDD分区通常来自多个父RDD分区,极端情况下,所有的父RDD分区都要进行重新计算。
二、DAG和Stage
1.DAG
DAG(Directed Acyclic Graph有向无环图)指的是数据转换执行的过程,有方向,无闭环(其实就是RDD执行的流程)
原始的RDD通过一系列的转换操作就形成了DAG有向无环图,任务执行时,可以按照DAG的描述,执行真正的计算(数据被操作的一个过程)
开始:通过SparkContext创建的RDD
结束:触发Action,一旦触发Action就形成了一个完整的DAG
注意:
一个Spark应用中可以有一到多个DAG,取决于触发了多少次Action
一个DAG中会有不同的阶段/stage,划分阶段/stage的依据就是宽依赖
一个阶段/stage中可以有多个Task,一个分区对应一个Task
2.Stage
DAG划分Stage
为什么要划分Stage? ——并行计算
一个复杂的业务逻辑如果有shuffle,那么就意味着前面阶段产生结果后,才能执行下一个阶段,即下一个阶段的计算要依赖上一个阶段的数据。那么我们按照shuffle进行划分(也就是按照宽依赖就行划分),就可以将一个DAG划分成多个Stage/阶段,在同一个Stage中,会有多个算子操作,可以形成一个pipeline(管道)流水线,流水线内的多个平行的分区可以并行执行
如何划分DAG的stage
对于窄依赖,partition(分区)的转换处理在stage中完成计算,不划分(将窄依赖尽量放在在同一个stage中,可以实现流水线计算)
对于宽依赖,由于有shuffle的存在,只能在父RDD处理完成后,才能开始接下来的计算,也就是说要划分stage(出现宽依赖即拆分)
总结
Spark会根据shuffle/宽依赖使用回溯算法来对DAG进行Stage划分,从后往前,遇到宽依赖就断开,遇到窄依赖就把当前的RDD加入到当前的stage/阶段中
三、名词解析
Application:用户编写的spark应用程序。
Application jar :包含spark的应用程序的jar包。
Driver :驱动程序,就是用来执行main方法的jvm进程,里面会执行一些Driver端的代码,如创建SparkContext,设置应用名,设置日志级别...
SparkContext :Spark运行时的上下文环境,用来和ClusterManager进行通信,并进行资源申请、任务的分配和监控等。
ClusterManager :集群管理器,对于Standalone模式,就是Master,对于Yarn模式就是ResoureManager/ApplicationMaster,在集群上做统一的资源管理进程
Worker :工作节点,是拥有CPU/内存等资源的机器,是真正干活的节点
Executor :运行在Worker中的jvm进程
RDD :弹性分布式数据集
DAG :有向无环图,就是根据Action形成的RDD的执行流程图----静态的图
Job :作业,按照DAG进行执行就形成了Job----按照图动态的执行
Stage :DAG中,根据shuffle依赖划分出来的一个个的执行阶段!
Task :被送到某个Executor上的工作单元,和hadoopMR中的MapTask和ReduceTask概念一样,是运行Application的基本单位,多个Task组成一个Stage,而Task的调度和管理等是由TaskScheduler负责。
TaskSet :任务集,就是同一个Stage中的各个Task组成的集合
四、Job调度流程
1、Driver启动创建SparkContext
2、SparkContext向ClusterManager注册申请资源
3、ClusterManager找Worker分配资源启动Executor
4、Executor等待Task提交
5、构建DAG
6、DAG Scheduler划分Stage
7、Task Scheduler提交Task
8、注销资源