目录
前言
RDD的五大特性之一就是RDD之间有依赖关系,描述了RDD如何从源头计算过来的。
这样可以做到容错,如果某一个RDD分区出现错误,可以根据依赖关系重新计算相关的分区,而不需要全部重新计算。
如果链路关系太长,可以checkpoint下来
本文主要介绍下窄依赖和宽依赖
一、窄依赖
一个父RDD的分区至多被子RDD的某个分区使用一次
1)一个父RDD和一个子RDD的分区是唯一映射的 例如map filter
2)多个父RDD和一个子RDD的分区是唯一映射的 例如union
3)特殊的join 没有shuffle
二、宽依赖
一个父RDD的分区会被子RDD的分区使用多次
例如join、groupByKey、reduceByKey、...ByKey 有shuffle、产生新的stage
三、使用WC演示窄依赖、宽依赖
代码
val lines = sc.parallelize(Array("hello,spark", "hello,flink", "hello,hadoop"))
val words = lines.flatMap(_.split(","))
val pair = words.map((_, 1))
val wc = pair.reduceByKey(_ + _)
wc.collect()
DAG图
四、窄依赖中的join
其实宽窄依赖通过以上的例子已经了解的差不多了。
下面来介绍其中的一个特例:窄依赖中的join
join的俩哥们是宽依赖(存在shuffle),分区数相同,join后的分区数也相同,则为窄依赖
val rdd1 = sc.parallelize(Array("zs", "ls", "ww"), 2).map((_, 1)).reduceByKey(_ + _)
val rdd2 = sc.parallelize(Array("hz", "sh", "bj","gz"), 2).map((_, 1)).reduceByKey(_ + _)
rdd1.join(rdd2,2).collect()
五、总结
窄依赖:父类只有一个孩子,不存在shuffle,例如map、filter
宽依赖:父类有多个孩子,存在shuffle,例如groupByKey、reduceByKey
需要注意的是:join的俩哥们如果是宽依赖(存在shuffle),并且分区数量相同,join后的结果也相同,则为窄依赖,其他情况的join为宽依赖。
在业务中,为了方便容错回溯,尽量少使用宽依赖。