spark宽依赖与窄依赖

窄依赖Narrow Dependency

父RDD和子RDD是一对一的依赖关系,如map,filter

宽依赖Shuffle Dependency

本质如其名,本质就是shuffle。如reduceByKey,groupyByKey

以wordcount为例,剖析图如下:


### 三、Spark 依赖窄依赖的区别特点 #### 窄依赖(Narrow Dependency) 在 Spark 中,**窄依赖**是指子 RDD 的每个分区只依赖于父 RDD 的一个分区。这种依赖关系通常出现在如 `map`、`filter`、`union` 等操作中。由于每个子分区的数据来源唯一,因此可以实现高效的流水线式计算,不需要进行数据的重新洗牌(shuffle)[^2]。 常见的窄依赖包括: - **OneToOneDependency**:子 RDD 分区父 RDD 分区一一对应。 - **RangeDependency**:用于 `union` 操作后生成的 RDD,其分区是父 RDD 分区的连续子集。 窄依赖的优势在于: - 数据流简单,易于并行处理。 - 不涉及 shuffle,执行效率高。 - 在故障恢复时更高效,因为只需重新计算失败的分区及其依赖的父分区。 ```java JavaRDD<String> lines = sc.textFile("hdfs://..."); JavaRDD<String> filtered = lines.filter(line -> line.contains("spark")); ``` 上述代码中的 `filter` 是典型的窄依赖操作,子 RDD 的每个分区只依赖于父 RDD 的对应分区[^4]。 #### 依赖(Wide Dependency) **依赖**是指子 RDD 的一个分区可能依赖于父 RDD 的多个分区。这种情况通常发生在需要进行数据重分布的操作中,例如 `groupByKey`、`reduceByKey`、`sortByKey` 和部分形式的 `join`。依赖会导致 shuffle 操作,即跨节点的数据传输和重新分组,从而带来较高的网络 I/O 开销[^1]。 常见的依赖包括: - **ShuffleDependency**:当子 RDD 的分区器(Partitioner)父 RDD 不一致或需要聚合操作时,会触发 shuffle。 依赖的特点如下: - 子 RDD 的每个分区依赖于多个父 RDD 分区。 - 触发 shuffle 操作,增加执行时间。 - 在调度上需要划分不同的 stage,每个 stage 内部由窄依赖组成,stage 之间通过 shuffle 边界隔开[^3]。 ```java JavaPairRDD<String, Integer> pairs = lines.mapToPair(s -> new Tuple2<>(s, 1)); JavaPairRDD<String, Integer> counts = pairs.reduceByKey((a, b) -> a + b); ``` 上述代码中,`reduceByKey` 操作导致依赖,因为每个键值对的归并操作需要将相同 key 的数据集中到同一个分区中[^5]。 #### 总结对比 | 特性 | 窄依赖 | 依赖 | |----------------|----------------------------|----------------------------------| | 是否触发 shuffle | 否 | 是 | | 分区依赖关系 | 子分区仅依赖一个父分区 | 子分区依赖多个父分区 | | 执行效率 | 高 | 相对较低 | | 故障恢复 | 只需恢复失败分区及父分区 | 需要恢复多个父分区 | | 常见算子 | map、filter、union | groupByKey、reduceByKey、join | 在实际开发中,应尽量使用窄依赖操作来优化性能,减少 shuffle 的发生[^2]。同时,合理设计分区策略(如使用合适的 Partitioner)也能有效降低依赖带来的性能瓶颈。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值