一、Mapreduce工作流程
(1)数据切片Split。数据切片数决定maptask并行度,默认情况下,一个切片大小=块大小。切片不是针对整体数据集,而是针对每一个文件单独切片,所以会有小文件问题(CombineTextInputFormat可用于小文件过多的场景,可以将多个小文件在逻辑上划分到一个切片中)。
(2)map。每个maptask并行执行,调用map方法对数据进行业务逻辑处理,并输出kv键值对。
(3)shuffle。shuffle过程从map方法输出outk outv键值对开始,键值对会被写入到环形缓冲区中,同时记录该条数据的分区信息(环形缓冲区一半记录数据的元数据信息,一半记录真实数据信息)当环形缓冲区写到80%的时候,环形缓冲区开始反向写入数据,并且已写入的80%数据开始溢写到磁盘(在真正写入磁盘之前,会在内存中首先按照key进行快速排序),一个mapTask可能会有多个溢写文件,这些文件在进入reduce之前,还会进行归并排序成一个大的溢写文件(如果有combiner,会在这先进行部分聚合)。reduceTask会从不同的mapTask主动拉取自己分区的数据,并对这些来自不同mapTask的数据再次进行归并排序,合并成一个大的文件,到这里shuffle阶段就结束了,之后就是调用reduce方法完成最终的聚合操作了。
(4)reduce。调用reduce方法,完成最后的逻辑聚合。
二、MapTask工作机制
一个MapTask总体上包含read、map、collect、溢写、merge五个阶段。
(1)read阶段。读取数据。
(2)map阶段。调用map方法处理输入的kv键值对。
(3)collect阶段。将map计算结果进行收集,写入到环形缓冲区。
(4)溢写阶段。环形缓冲区达到80%时会进行溢写,注意溢写前会先进行快排。
(5)merge阶段。一个maptask的多个溢写文件进行归并,形成一个大的溢写文件。
三、ReduceTask工作机制
一个ReduceTask总体上包含Copy、Sort、reduce三个阶段。
(1)Copy阶段。从不同的Maptask主动拷贝自己分区的数据文件。
(2)Sort阶段。对来自不同maptask的文件进行归并排序,整合为一个文件。
(3)reduce阶段。调用reduce方法,按照聚合逻辑进行聚合运算。
四、Shuffle机制
map方法结束到reduce方法之前的过程都属于shuffle过程。shuffle过程的理解主要就是三次排序过程(一次快排,两次归并)。
(1)一个maptask在溢写每个文件到磁盘前,都会在内存中对不同的分区内部进行快排,保证了每个溢写文件内部的分区内有序
(2)一个maptask可能会有多个溢写文件,每个溢写文件都划分了分区且分区内有序,这些溢写文件会进行归并排序合并成一个大的溢写文件,保留分区且分区内有序
(3)reduceTask会主动从不同的maptask拉取自己分区的数据,从不同maptask拷贝的文件在进入reduce方法之前还会进行一次归并排序。
五、部分调优参数
(1)shuffle中的缓冲区大小会影响溢写次数,缓冲区越大,溢写次数越少,磁盘的io越少,执行速度越快。缓冲区大小可以通过mapreduce.task.io.sort.mb参数进行调整。