RDD和它依赖的父RDD(s)的关系有两种不同类型,即窄依赖(narrow dependency)和 宽依赖(wide dependency)
窄依赖:
一:map、filter执行的方法有三个分区,分别在三个不同的机器上,对其进行map、filter操作,生成的新的数据还在原来的机器上,子依赖和父依赖的数据的分区一一对应
二:union(并集):执行操作前有两个RDD,假如第一个RDD的数据分区对应的机器是node-1和nod-2,第二个分区对应的机器是node-3和node-4,合并之后成为一个RDD,该RDD有四个分区,他的数据位置也没有发送变化,分区的数据和执行操作前数据一一对应
三:join with inputs co-partitioned:执行操作前有两个RDD,执行操作后生成一个新的RDD,该方法进行了网络传输,假如执行操作前的数据对应的机器为node-1~6,执行操作后的分区为node-1~3,只不过是子RDD一个分区的数据来自与两个分区的数据
举例:
注:这时候,我们的join操作就是窄依赖
窄依赖是指每个父RDD的一个分区的数据最多被子RDD的一个分区所使用,例如map、filter、union等操作都会产生窄依赖;
需要特别说明的是对join操作有两种情况:如果两个RDD在进行join操作时,一个RDD的partition仅仅和另一个RDD中已知个数的Partition进行join,那么这种类型的join操作就是窄依赖,例如图1中左半部分的join操作(join with inputs co-partitioned);其它情况的join操作就是宽依赖,例如图1中右半部分的join操作(join with inputs not co-partitioned),由于是需要父RDD的所有partition进行join的转换,这就涉及到了shuffle,因此这种类型的join操作也是宽依赖。
宽依赖:
宽依赖是指一个父RDD的分区数据会被多个子RDD的Partition所使用,例如groupByKey、reduceByKey、sortByKey等操作都会产生宽依赖;
举例:
总结:在这里我们是从父RDD的partition被使用的个数来定义窄依赖和宽依赖,因此可以用一句话概括下:如果父RDD的一个Partition被子RDD的一个Partition所使用就是窄依赖,否则的话就是宽依赖。因为是确定的partition数量的依赖关系,所以RDD之间的依赖关系就是窄依赖;由此我们可以得出一个推论:即窄依赖不仅包含一对一的窄依赖,还包含一对固定个数的窄依赖。
一对固定个数的窄依赖的理解:即子RDD的partition对父RDD依赖的Partition的数量不会随着RDD数据规模的改变而改变;换句话说,无论是有100T的数据量还是1P的数据量,在窄依赖中,子RDD所依赖的父RDD的partition的个数是确定的,而宽依赖是shuffle级别的,数据量越大,那么子RDD所依赖的父RDD的个数就越多,从而子RDD所依赖的父RDD的partition的个数也会变得越来越多。
Shuffle的定义:
Shuffle的含义是洗牌,将数据打散,父RDD的一个分区的数据如果给了子RDD的多个分区(只有存在这种可能),就是Shuffle
Shuffle会有网络传输数据,但有网络传输,并不意味着就是Shuffle