Spark窄依赖与宽依赖的区别
请解释Spark中的窄依赖(Narrow Dependency)和宽依赖(Wide Dependency/Shuffle Dependency)的区别,以及如何根据依赖关系划分Stage。
回答
孤独的心
窄依赖(Narrow Dependency):
- 父RDD的每个分区最多被一个子RDD分区使用
- 操作示例:
map()、filter()、flatMap()、union()、mapPartitions() - 计算特点: 可在同一个Stage内**流水线式(Pipelining)**执行,无需Shuffle
- 容错恢复: 只需重新计算丢失分区的父分区,非常高效
宽依赖(Wide Dependency / Shuffle Dependency):
- 父RDD的每个分区可被多个子RDD分区使用
- 操作示例:
groupByKey()、reduceByKey()、join()、repartition()、sortByKey() - 计算特点: 需要Shuffle(数据跨节点混洗),产生Stage边界
- 容错恢复: 需要重算所有父分区,代价较大
Stage划分规则(DAGScheduler):
- 从最后一个RDD开始反向遍历
- 遇到宽依赖时创建一个新的Stage(即:宽依赖是Stage的边界)
- 窄依赖的转换合并到同一个Stage中
- Stage分为:
- ShuffleMapStage:产生Shuffle输出的中间Stage
- ResultStage:执行最终Action操作的Stage
示例:
rdd1.map() → rdd2.filter() → rdd3.groupByKey() → rdd4.map() → rdd5.count()
Stage0: [map, filter] ← 窄依赖,无需Shuffle
Stage1: [groupByKey, map] ← Shuffle边界
Stage2: [count] ← ResultStage