共计 2194 个字符,预计需要花费 6 分钟才能阅读完成。
本文以宽依赖和窄依赖的例子来解说 stage 切分的过程,这里跟之前不一样的是,join 操作是宽依赖 。
为了看的更不便一些,咱们把上一篇的最终的图片简化一下,能够看到多了 4 个灰色的 RDD,这是因为有些转换,比方 join,外面还有做一些其余的转换操作。
数据的流程是右边到左边的,stage 的切分流程是相同的,是从左边到右边。次要的操作是从左边往左边走,碰到 shuffle 依赖后,就会把他当做本人的 stage 的父节点。stage 的父节点也会往左边,看看有没有 shuffle 依赖,反复着下面的过程,直至所有 RDD 都走完。这样说有些形象,上面用图形一步步解说 stage 切分的全过程。
RDD[11]
首先拿到的是最左边的 RDD[11],会把 RDD[11]压入 waitingForVisit 栈中,这个 waitingForVisit 栈就是寄存窄依赖的,而后通过窄依赖的依赖去查找 shuffle 依赖。此外还有两个数据结构,parents 汇合,用来寄存 shuffle 依赖,visited 汇合,用来寄存曾经遍历过的 RDD。
此时 waitingForVisit 栈中曾经有 RDD,就会把 RDD[11]拿进去,RDD[11]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[11]的依赖 RDD[10]是窄依赖,所以 RDD[10]就会压入 waitingForVisit 栈中。
waitingForVisit 栈发现还有 RDD,就会把 RDD[10]拿进去,RDD[10]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[10]的依赖 RDD[9]是窄依赖,所以 RDD[9]就会压入 waitingForVisit 栈中。
waitingForVisit 栈发现还有 RDD,就会把 RDD[9]拿进去,RDD[9]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[9]的依赖 RDD[4]、RDD[8]是 shuffle 依赖,所以 RDD[4]、RDD[8]会放入 parents 汇合。
waitingForVisit 栈曾经为空了,所以就能够开始创立 stage。这个 stage 是左边的,所以还要看看他是否有父节点,也就是是否还有 shuffle 依赖,这个查找的过程,跟下面一样。
RDD[8]
RDD[11]中的 shuffle 依赖 RDD[8]压入 waitingForVisit 栈中。
此时 waitingForVisit 栈中曾经有 RDD,就会把 RDD[8]拿进去,RDD[8]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[8]的依赖 RDD[6]、RDD[7]是窄依赖,所以 RDD[6]、RDD[7]就会压入 waitingForVisit 栈中。
waitingForVisit 栈发现还有 RDD,就会把 RDD[7]拿进去,RDD[7]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[7]没有任何依赖,于是不做解决。
waitingForVisit 栈发现还有 RDD,就会把 RDD[6]拿进去,RDD[6]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[6]的依赖 RDD[5]是窄依赖,所以 RDD[5]就会压入 waitingForVisit 栈中。
waitingForVisit 栈发现还有 RDD,就会把 RDD[5]拿进去,RDD[5]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[5]没有任何依赖,于是不做解决。
waitingForVisit 栈曾经为空了,这次 RDD[8]并没有任何 shuffle 依赖,于是间接创立 id 为 0 的 stage0。
RDD[4]
RDD[11]中的 shuffle 依赖 RDD[8]曾经解决了,而后 shuffle 依赖 RDD[4]压入 waitingForVisit 栈中。
此时 waitingForVisit 栈中曾经有 RDD,就会把 RDD[4]拿进去,RDD[4]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[8]的依赖 RDD[3]是窄依赖,所以 RDD[3]就会压入 waitingForVisit 栈中。
waitingForVisit 栈发现还有 RDD,就会把 RDD[3]拿进去,RDD[3]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[3]的依赖 RDD[2]是窄依赖,所以 RDD[2]就会压入 waitingForVisit 栈中。
waitingForVisit 栈发现还有 RDD,就会把 RDD[2]拿进去,RDD[2]是没有遍历过的,所以会放入 visited 汇合,另外 RDD[2]的依赖 RDD[1]、RDD[0]是 shuffle 依赖,所以 RDD[1]、RDD[0]会放入 parents 汇合。
waitingForVisit 栈曾经为空了,所以又开始创立 stage 了。
因为 RDD[1]、RDD[0]没有父节点,于是就间接 id 为 1、2 的 stage1 和 stage2。
而后咱们回到 RDD[4],为 RDD[4]创立 stage,因为他 shuffle 依赖为 stage1 和 stage2,所以 RDD[4]创立了一个 id 为 3,父节点为 stage1 和 stage2 的 stage3。
RDD[11]
咱们再回到 RDD[11],此时他的 shuffle 依赖 RDD[4]和 RDD[8]都曾经创立好了 stage,所以 RDD[11]创立了一个 id 为 4,父节点为 stage3 和 stage0 的 stage4。至此,stage 创立实现。