Spark按指定列排序后写入HDFS的执行逻辑相关问题
Spark 全局排序写入执行逻辑解答
1. 排序场景的写入执行流程
Spark的排序写入逻辑完全取决于你需要的是分区内有序还是全局有序,两种场景差异极大:
- 如果仅要求分区内有序:调用
sortWithinPartitions算子即可,逻辑计划不会触发Shuffle,每个executor处理完所属原始分区后,直接对本分区内的数据按指定列排序,排序完成即可独立写入文件系统,无需等待其他executor执行完成,这种场景下最终全量数据是不全局有序的,仅单个输出文件内部有序。 - 如果要求全量数据全局有序:调用
sortBy/orderBy算子,此时会触发Shuffle阶段,执行流程如下:- 首先Spark会基于排序列采样生成
RangePartitioner,将排序列的全局取值范围拆分为N个连续、无重叠、按排序规则单调递增/递减的区间,每个区间对应一个最终输出分区 - 所有executor的上游计算完成后,将数据按所属区间Shuffle分发到对应目标executor的分区中,该阶段必须等全量数据分发完成才会进入下一步
- 每个executor拿到所属区间的全量数据后,对本分区数据做本地排序,排序完成即可独立写入文件系统,无需等待其他executor
- 首先Spark会基于排序列采样生成
2. 全局有序的保障机制
Spark不需要等所有executor都写完再做统一聚合,仅靠两个规则就能保障全量数据全局有序:
- 范围分区的区间本身严格遵循排序规则:比如按ID升序排序时,第一个分区存储ID最小的区间,第二个分区存储次小区间,最后一个分区存储ID最大的区间,分区的编号顺序完全匹配排序的全局顺序
- 最终输出的文件名携带分区编号:比如
part-00000对应第一个分区的输出,part-00001对应第二个分区的输出,以此类推,只要按文件名的编号顺序读取所有输出文件,得到的全量数据就是全局有序的
注:如果要求最终输出为单个有序文件,Spark会将范围分区的数量设为1,所有数据都会Shuffle到同一个executor上排序后写入,该场景仅适合小数据量,大数据量下会出现单节点性能瓶颈。
内容的提问来源于stack exchange,提问作者Neethu Lalitha
相关产品推荐
相关产品推荐

