Spark依赖关系与Stage划分简介

Spark会在用户提交的计算逻辑中的RDD的转换和动作来生成RDD之间的依赖关系,同时这个计算链也就生成了逻辑上的DAG(有向无环图)。

RDD之间的关系可以从两个维度来理解:一个是当前RDD是从哪些RDD转换而来,也就是parent RDD(s)是什么;还有就是依赖于parent RDD的哪些Partition。这个关系,就是RDD之间的依赖。根据依赖parent RDD的Partitions的依赖情况,spark将依赖分为两种,一种是窄依赖,一种是宽依赖。

RDD之间的依赖关系

窄依赖指的是每一个parent RDD的Partition最多被子RDD的一个Partition使用。

Spark依赖关系与Stage划分简介

宽依赖指的是多个子RDD的Partition会依赖同一个parent RDD的Partition。

Spark依赖关系与Stage划分简介

对于窄依赖而言,它们只是将Partition的数据根据转换的规则进行转化,并不涉及其他处理,可以简单的认为只是将数据从一个形式转换到另一个形式。因此对于窄依赖,并不会引入昂贵的shuffle。所以执行效率会很高。如果整个DAG中存在多个连续的窄依赖,则可以将这些连续的窄依赖整合到一起连续执行,中间不执行shuffle从而提高效率,这样的优化方式称之为流水线优化。此外,针对于窄依赖,如果子RDD的某个分区数据丢失,只需要找到父RDD对应依赖的分区恢复即可。

对于宽依赖而言,子RDD的Partition是parent RDD的所有Partition是parent  RDD的所有Partition Shuffle的结果。

DAG的生成

原始的RDD通过一系列转换就形成了DAG。RDD之间的依赖关系,包含了RDD由哪些Parent RDD转换而来和它依赖parent RDD的哪些Partitions,是DAG的重要属性。

借助这些依赖关系,DAG可以认为这些RDD之间形成了Lineage(血缘关系)。借助Lineage,能保证一个RDD被计算前,它所依赖的parent RDD都已经完成了计算;同时,也是实现了RDD的容错性,即如果一个RDD的部分或者全部的计算结果丢失了,那么就需要重新计算这部分数据。

Spark中的stage

Spark在处理任务时,会根据依赖关系,将DAG划分为不同的阶段(Stage)。

处理的流程是:

        1.Spark在执行Transformation类型的操作时时,都不会立即执行,而是懒执行; 

        2.执行若干步的Transformation类型的操作后,一旦遇到Action类型的操作时,才会真正触发执行

        3.执行时,从当前Action方法向前回溯,如果遇到窄依赖则应用流水线优化,继续向前找,直到碰到某一个宽依赖

        4.因为宽依赖必须要进行shuffle操作,无法实现优化,所以将这一次段执行过程组装成一个stage

        5.再从当前宽依赖开始继续向前寻找。重复刚才步骤,从而将整个DAG划分成若干个stage

Spark依赖关系与Stage划分简介

         

如上图所示,RDD(A)在生成RDD(B)的过程中执行了groupBy操作,A和B之前的依赖关系为宽依赖,所以RDD(A)划分为Stage1。RDD(C)生成RDD(D)以及RDD(D)和RDD(E)在进行union操作,生成RDD(F)的过程中,其依赖关系均为窄依赖,这两个过程可以划分为stage2。

RDD(B)与RDD(F)进行join操作,生成RDD(G)的过程,存在宽依赖,所以这个过程划分为stage3。

上一篇:Exchange 2019 DAG配置


下一篇:Cookie客户端缓存.Session.Application