shuffle是昂贵操作,因为shuffle操作不仅涉及到数据的拉取、溢写磁盘的IO操作还涉及排序合并等操作,如果能让shuffle的成本尽量降低也是一大优化的方向。本篇文章对应Hadoop2.6.5,只对应流程,具体细节,可以研究MapTask/ReduceTask/Shuffle等源码。
shuffle过程
一、Map端
1、起始点 - map任务已产生结果将写出
这一阶段可以称作缓冲区写出。在map任务完成后会将结果写入缓冲区,缓冲区的大小设置好了就是固定的,当写出的数据长度超过缓冲区剩余空间大小时,已写入缓冲区的结果将被溢写到磁盘上。
2、溢写过程 - 对应 sortAndSpill
每次溢写都产生一个溢写文件,写出之前对缓冲区数据进行排序(排序方式有两个:堆排序、快速排序,可以通过 “map.sort.class” 设置, 默认是快速排序,排序规则是先按 partition 排再按 key 排)。
可知,写出时同一 partiton 的数据 append 在一起。而且,如果设置了 combiner , 会对相同 key 进行 combine 操作,也就是 map 端 reduce。写出之后产生一个对应溢出文件的索引文件。
也就是说对于每一次溢出操作,都产生一个文件,这个文件中的数据是按分区和键排好序的。对于一个map任务