这是我参与「第四届青训营 」笔记创作活动的第5天。
Shuffle概述
- 在最初的大数据计算工具MR任务中的map与reduce间需要进行Shuffle
- Map阶段:是在集群中各单机上进行小块数据的计算
- Shuffle阶段,在map阶段计算之后,将结果数据移动分发,为后续的reduce阶段做准备。
- reduce 阶段,对移动后的数据进行处理,直接进行结果聚合。
- 在大数据场景下,数据shuffle表示了不同分区数据交换的过程,不同的shuffle策略性能差异较大。
- 目前在各个引擎中shuffle都是优化的重点,在spark框架中,shuffle是支撑spark进行大规模复杂数据处理的基石。
- Shuffle 实现的发展历程
- Spark 0.8及以前 Hash Based Shuffle
- Spark 0.8.1为Hash Based Shuffle引入File Consolidation机制
- Spark 0.9引入ExternalAppendOnlyMap
- Spark 1.1引入Sort Based Shuffle,但默认仍为Hash Based Shuffle
- Spark 1.2默认的Shuffle方式改为Sort Based Shuffle
- Spark 1.4引入Tungsten-Sort Based Shuffle
- Spark 1.6 Tungsten-Sort Based Shuffle并入Sort Based Shuffle
- Spark 2.0 Hash Based Shuffle退出历史舞台
Shuffle算子
- Spark中会产生shuffle的算子大概可以分为4类
- repartition:重新选择分区
- Bykey:通过键分类
- join:聚合
- distinct:归类
- Spark中对shuffle的抽象:宽依赖(一对多)、窄依赖(一对一)
Shuffle过程
hash shuffle (2.0之后弃用)
- hash shuffle 运行时步骤:
- spark根据key将结果hash到不同buffer;
- map完成后buffer溢写到磁盘文件,一个buffer一个文件;
- task拉取小文件;
- 问题:
- 磁盘文件不合并,使用大量小文件,文件io频繁;
- 使用大量buffer内存,易出现oom。
sort shuffle
- sort shuffle 运行时步骤:spill、排序、合并。
- 问题:需要排序、同样产生小文件影响io效率。
bypass机制:BypassMergeShuffleWriter
- 不需要排序,节省时间
- 写操作的时候会打开大量文件
- 类似于Hash Shuffle,区别在于最后会合并为一个文件
UnsafeShuffleWriter
- 使用类似内存页储存序列化数据
- 数据写入后不再反序列化
- 只根据partition 排序Long Array,数据不移动
Push Shuffle(Spark3.2.0)
- 在mapper执行后自动合并数据,将数据push-merge复制一份到远程shuffle,供reducer读取。
- 基于原生的shuffle netty协议、以及Spark的mapper、reducer实现,用于解决大量随机磁盘IO的问题。