文章目录
- DAG
- Job与Action之间的关系
- DAG和分区
- DAG宽窄依赖
- DAG宽窄依赖的划分
- Spark内存迭代计算
- 总结
- Spark是怎么做内存计算的?DAG的作用?Stage阶段划分作用?
- Spark为什么比MapReduce快?
DAG
- Spark的核心是根据RDD来实现的,Spark Scheduler则为Spark核心实现的重要一环,其作用就是任务调度。Spark的任务调度就是如何组织任务去处理RDD中每个分区的数据,根据RDD的依赖关系构建DAG,基于DAG划分Stage,将每个Stage中的任务发到指定节点运行。基于Spark的任务调度原理,可以合理规划资源利用,做到尽可能用最少的资源高效地完成任务计算。
- DAG也叫有向无环图,即有方向,没有闭环的图,如下WordCount DAG图所示:
- DAG作用就是表示代码的逻辑执行流程。
Job与Action之间的关系
- 通常一个Action会产生一个DAG,会在程序中产生一个Job,所以一个Action = 一个DAG = 1个Job。之间的层级关系:1个application中可以包含多个job,每个Job中有一个DAG,每个Job是由一个Action产生的。
DAG和分区
- DAG是Spark代码的逻辑执行图,这个DAG的最终作用就是为了构建物理上的Spark详细执行计划,所以由于Spark是分布式多分区的,DAG与分区之间还是有关联的。还是以上图WordCount DAG图为例,该图在textFile步骤上就执行3分区,全部的RDD就在3个分区上执行。
DAG宽窄依赖
- 窄依赖:父RDD的一个分区,全部将数据发给子RDD一个分区。
- 宽依赖(shuffle):父RDD的一个分区,将数据发给子RDD多个分区。
- 我们可以看下图来真正地去理解宽窄依赖。
DAG宽窄依赖的划分
- Spark根据DAG的宽窄依赖划分为不同的DAG阶段,划分依据是从后往前,遇到宽依赖就会划分出一个阶段,这个阶段也称为stage。如下图所示:
- 该图在DAG中,基于宽依赖,将DAG划分成了2个stage,后面的为stage0,前面的为stage1,在stage内部一定都是窄依赖。
Spark内存迭代计算
- 根据上图的描述,基于带有分区的DAG以及阶段划分,可以从图中得到逻辑上最优的task分配,一个task是由一个线程来具体执行的,task对于rdd这一条执行的计算过程的直线(纯内存计算)也叫内存计算管道。
- Spark默认收到了全局并行度的限制,除了个别算子由特殊分区的情况,大部分算子都会遵循全局并行度要求,来规划自己的分区数。Spark一般推荐只设置全局的并行度,不要再算子上再加上并行度(除了一些排序算子外)。
总结
Spark是怎么做内存计算的?DAG的作用?Stage阶段划分作用?
- Spark会产生DAG图。
- DAG图会基于分区和宽窄依赖关系划分阶段。
- 一个阶段内部都是窄依赖,窄依赖内,如果形成前后的1:1的分区对应关系,就可以产生许多内存迭代计算管道。
- 这些内存迭代计算的管道,就是一个个具体执行的Task。
- 一个Task就是一个具体的线程,任务跑在一个线程内,就是走内存计算了。
Spark为什么比MapReduce快?
- 从编程模型上来看,Spark算子多,处理速度快。MR编程模型很难在一套MR中处理复杂任务,需要些多套MR进行串联,多个MR串联通过磁盘交互数据,就很慢。Spark可以执行内存迭代,算子间形成DAG基于依赖划分阶段后,在阶段内形成内存迭代管道,但是MR的交互还是通过磁盘来实现。所以速度就很慢。