发布网友 发布时间:2022-04-25 03:14
共3个回答
热心网友 时间:2023-05-20 21:10
1. 窄依赖与宽依赖
针对不同的转换函数,RDD之间的依赖关系分为窄依赖(narrow dependency)和宽依赖(wide dependency,也成shuffle dependency)。
1.1 窄依赖
窄依赖是指1个父RDD分区对应1个子RDD的分区。换句话说,一个父RDD的分区对应于一个子RDD的分区,或者多个父RDD的分区对应于一个子RDD的分区。所以窄依赖又可以分为两种情况:
1个子RDD的分区对应于1个父RDD的分区,比如map,filter,union等算子
1个子RDD的分区对应于N个父RDD的分区,比如co-partioned join
1.2 宽依赖
宽依赖是指1个父RDD分区对应多个子RDD分区。宽依赖有分为两种情况
1个父RDD对应非全部多个子RDD分区,比如groupByKey,receByKey,sortByKey
1个父RDD对应所有子RDD分区,比如未经协同划分的join
窄依赖与宽依赖.png
总结:如果父RDD分区对应1个子RDD的分区就是窄依赖,否则就是宽依赖。
2. 为什么Spark将依赖分为窄依赖和宽依赖
2.1 窄依赖(narrow dependency)
可以支持在同一个集群Executor上,以pipeline管道形式顺序执行多条命令,例如在执行了map后,紧接着执行filter。分区内的计算收敛,不需要依赖所有分区的数据,可以并行地在不同节点进行计算。所以它的失败回复也更有效,因为它只需要重新计算丢失的parent partition即可
2.2 宽依赖(shuffle dependency)
则需要所有的父分区都是可用的,必须等RDD的parent partition数据全部ready之后才能开始计算,可能还需要调用类似MapRece之类的操作进行跨节点传递。从失败恢复的角度看,shuffle dependency牵涉RDD各级的多个parent partition。
3. DAG
RDD之间的依赖关系就形成了DAG(有向无环图)
在Spark作业调度系统中,调度的前提是判断多个作业任务的依赖关系,这些作业任务之间可能存在因果的依赖关系,也就是说有些任务必须先获得执行,然后相关的依赖人物才能执行,但是任务之间显然不应出现任何直接或间接的循环依赖关系,所以本质上这种关系适合用DAG表示
4. stage划分
由于shuffle依赖必须等RDD的父RDD分区数据全部可读之后才能开始计算,因此Spark的设计是让父RDD将结果写在本地,完全写完之后,通知后面的RDD。后面的RDD则首先去读之前RDD的本地数据作为输入,然后进行运算。
由于上述特性,讲shuffle依赖就必须分为两个阶段(stage)去做:
(1)第1个阶段(stage)需要把结果shuffle到本地,例如receByKey,首先要聚合某个key的所有记录,才能进行下一步的rece计算,这个汇聚的过程就是shuffle。
(2) 第二个阶段(stage)则读入数据进行处理。
为什么要写在本地?
后面的RDD多个分区都要去读这个信息,如果放到内存,假如出现数据丢失,后面所有的步骤全部不能进行,违背了之前所说的需要父RDD分区数据全部ready的原则。
同一个stage里面的task是可以并发执行的,下一个stage要等前一个stage ready(和map rece的rece需要等map过程ready一脉相承)。
Spark 将任务以 shuffle 依赖(宽依赖)为边界打散,划分多个 Stage. 最后的结果阶段叫做 ResultStage, 其它阶段叫 ShuffleMapStage, 从后往前推导,依将计算。
RDD的划分.png
1.从后往前推理,遇到宽依赖就断开,遇到窄依赖就把当前RDD加入到该Stage
2.每个Stage里面Task的数量是由该Stage中最后一个RDD的Partition的数量所决定的。
3.最后一个Stage里面的任务类型是ResultTask,前面其他所有的Stage的任务类型是ShuffleMapTask。
4.代表当前Stage的算子一定是该Stage的最后一个计算步骤
表面上看是数据在流动,实质上是算子在流动。
热心网友 时间:2023-05-20 21:10
窄依赖是指父RDD的每个分区只被子RDD的一个分区所使用,子RDD分区通常对应常数个父RDD分区(O(1),与数据规模无关)
相应的,宽依赖是指父RDD的每个分区都可能被多个子RDD分区所使用,子RDD分区通常对应所有的父RDD分区(O(n),与数据规模有关)
简单来说, 就是窄依赖是一对一或者多对一, 宽依赖就是多对多或者一对多
窄依赖,如果一个part失败了,只需要固定几个父part重跑,宽的就需要所有的都重跑了
两个或者固定几个part合到一个part,起到减少分区的作用,这个也是窄依赖,比如coalese
要知道part是一个逻辑概念,可能是对应多个文件,当coalese时不会真的执行把多个分区合成一个分区,而是在rdd处理的时候,按照映射关系直接去取就好了,不存在shuffle过程!
热心网友 时间:2023-05-20 21:11
宽依赖性是指对于某个输入的信息,当这个信息不存在的时候,系统也能正常工作;而窄依赖性是指当这个信息不存在时,系统会出现故障。比如,一个人不吃饭,可以活一个星期。但是,如果这个人不喝水,可能只能活一天。这个就是宽依赖性。窄依赖性的例子就是一个人不吃饭可能会饿死,但是一个人不喝水可能就会渴死。所以,一个人如果没有了水,可能会死,但是如果有了水就不会死了。