Spark2.0X版本前,使用的是hashShuffle和优化过后的hashShuffle两种模式,
Spark2.0X版本后,开始使用sortShuffle和bypass模式下的sortShuffle两种模式,
那么为什么从Spark2.0X版本开始要弃用hashShuffle模式呢?
个人理解如下:
在Spark中Executor的一个core一次性只能处理一个task的数据,
在Spark中一个partition对应一个task,
首先Spark的hashShuffle模式,是依据reducetask的个数,进行hash散列分散数据到不同的分区,一个task的数据溢写到一个磁盘file中,一个file对应一个reducetask去读取,这种shuffle模式的缺点是小文件过多,就算优化后小文件依旧过多
而Spark的sortShuffle模式,对数据进行sort全排序,然后写入磁盘,一个task只生成一个file文件;并且在索引文件中记录了每个reducetask需要拉取的那部分数据的start offset和end offset,所以reducetask在拉取file数据前需要先读取索引文件,然后再去数据结构中拿到相应的那部分切片数据。
采用sortShuffle起到了两点好处:
1. 小文件明显变少了,一个task只生成一个file文件
2. file文件整体有序,加上索引文件的辅助,查找变快,虽然排序浪费一些性能,但是查找变快很多
而在shuffle read task(mapper)数量小于默认值200时,启用bypass模式的sortShuffle,并没有进行sort,原因是数据量本身比较少,没必要进行sort全排序,因为数据量少本身查询速度就快,正好省了sort的那部分性能开销。