Shuffle产生的三种场景
Shuffle产生的三种场景
shuffle 三大功能【分区、排序、分组】
1.重分区:repartition:分区个数由小变大的时候
重分区的本质是改变数据与分区的映射关系,当目标分区数≠原分区数,且无法通过 “同节点内合并分区”(仅 coalesce 缩容且 shuffle=false)实现时,必须通过 Shuffle 调用分区器(如 HashPartitioner),将原分区数据拆分 / 合并后分发到新分区,确保数据均匀分布。
因为重分区需要调用分区器对所有数据进行重新分区
举例:rdd1:两个分区
· part0: 1 2 3
· part1: 4 5 6
重分区得到rdd2:调用分区器【只有shuffle阶段才能调用分区器】
Shuffle 传输
· part0: 0 6
· part1: 1 4
· part2: 2 5
2.全局排序:sortBy
全局排序(如 sortBy、sortByKey)无法仅靠单个分区局部排序实现,必须先通过 Shuffle 做范围分区(由 RangePartitioner 实现):先采样全量数据确定 “分区边界”(如按排序键划分连续范围),再将数据按边界分发到对应分区,最后每个分区内局部排序 —— 最终 “分区间有序 + 分区内有序” 即实现全局有序。
· part0: 1 2 5
· part1: 4 3 6
方案:将所有数据放入磁盘
实现:对数据做了范围分区:将所有数据做了采样:例如采样假设中位数是4
Shuffle 传输
· part0: 5 4 6
· part1: 1 2 3 在让每一个task对每一个分区进行降序排序
得到
· part0: 6 5 4
· part1: 3 2 1
相当于两个分区要排序,先取一个数作为中间数,然后比他小的放在第一个分区,比他大的放在第二个分区,对每一个分区进行排序,最终完成排序
3.全局分组: groupBy,reduceByKey
全局分组(如 groupBy、reduceByKey)的核心是 “将散落在不同分区的同 Key 数据汇总到同一个分区”,这必须通过 Shuffle 实现:先在 Map 端对数据按 Key 标记 “目标分区”(由分区器决定,同 Key 必映射到同一分区),再通过 Shuffle 将同 Key 数据传输到目标分区,最后在 Reduce 端执行分组 / 聚合。
·part0:[(1, 10), (2, 20), (1, 30)]
·part1:[(2, 40), (3, 50), (1, 60)]
预聚合
·part0:[(1, 40), (2, 20)]
·part1:[(2, 40), (3, 50), (1, 60)]
Shuffle 传输
·part0:[(2, 40), (2, 20)]
·part1:[(1, 40), (3, 50), (1, 60)]
总结:Shuffle 在三大场景中的核心作用
本质上,Shuffle 都是为了解决 “数据跨分区 / 跨节点重组”,只是不同场景的 “重组目标” 不同:
重分区:重组目标是 “数据与新分区匹配”;
全局排序:重组目标是 “数据按排序范围拆分到对应分区”;
全局分组:重组目标是 “同 Key 数据汇聚到同一分区”。所有场景的 Shuffle 性能优化,核心都是 “减少跨节点传输的数据量”(如预聚合、合理分区数)。