Spark的shuffle分为老版本的HashShuffle(现在已经弃用)和新版本的SortShuffle。Shuffle过程发生在宽依赖切分Stage的过程中,前一个Stage称作ShuffleMap Stage,后一个Stage称作Result Stage。
HashShuffle原理
未经优化的HashShuffle
1.Map Task将数据写入buffer缓冲区,待缓冲区达到阈值时开始溢写文件,文件数量取决于(等于)Reduce Task的数量。Reduce Task的数量取决于(等于)上一个Stage的最后一个RDD的分区数。
2.Reduce Task一边拉取对应分区的数据到buffer缓存中,一边进行处理,使用map方法对数据进行归并,直至所有的数据归并结束。
3.未经优化的Hash Shuffle每个map task都会为下游的每个reduce task创建一个磁盘文件。如果有50个map task,100个renduce task,那么就会产生5000个小文件,产生过多的小文件,极大的影响了shuffle write的性能。
优化后的HashShuffle
1.设置consolidateFiles为true,开启优化机制。
2.开始优化机制后,就不再是每个map task为下游的每个reduce task生成一个磁盘文件,而是一个executor为一个reduce task生成一个磁盘文件。
3.consolidateFiles机制允许多个map task复用同一个磁盘文件,可以在一定程度上对map task的数据进行合并,从而大幅减小磁盘文件的数量,提升shuffle write性能。
Sort Shuffle
普通运行机制
1.普通运行机制下,map task会先将数据写入到内存缓冲区中,当内存缓冲区中的数据达到一定阈值时,开始进行溢写。
2.溢写到磁盘之前,先按照数据的key进行排序,排序后分批次写入磁盘, 默认每批次1w条数据。
3.数据溢写到磁盘的过程中会产生多个临时磁盘文件,临时磁盘文件会进行merge归并,最终一个map task只会生成一个归并后的磁盘文件,同时还是生成一个对应的索引文件,记录数据的offset信息。
4.reduce task拉取对应分区的数据进行处理。
bypass运行机制
1.bypass运行机制触发需要满足两个条件:①不是聚合类型的shuffle算子;②map task的数量小于bypassMergeThreshold的值,默认是200。
2.bypass运行机制,map task数据溢写到磁盘之前不会对数据进行排序。
3.bypass运行机制,数据的溢写规则和未经优化的hashshuffle一样,每个map task都会为下游的每个reduce task生成一个文件,但是最后会进行数据的归并,合并为一个磁盘文件。
4.bypass机制的好处就是不对数据进行排序,节省了这一部分的资源开销。