①map的执行结果会被Outercollector组件收集,outercollector会将数据写入环形缓冲区内,
进行数据写入的时候根据map输出的key生成一个分区号,默认的是key.hashCode()&Integer_MAX_VALUE%reducetask获取分区号。如果用户自定义分区算法,则按照用户自定义的分区进行返回。
②环形缓冲区默认大小为100M,阈值为80%,当达到阈值的时候会开启一个溢写线程,将环形缓冲区的数据向磁盘溢写,溢写之前需要做一些工作
③溢写之前会会环形缓冲区内的数据进行排序,先根据分区号进行排序,这个排序内部是双层 for循环
作用是将相同分区的数据写在一起,再根据map输出的key值进行排序,作用是将key相同的数据放在一起
④溢写到磁盘,形成一个个溢写文件,溢写的时候会根据元数据到对应的原始数据中获取原始数据进行溢写。一个mapTask会对应多个溢写文件
⑤对溢写文件进行归并,在归并的时候会再进行一次排序,排完序之后的文件就会按分区和map的key放在一起,并且分区之间会有标记
⑥reduceTask会通过MRAppmaster获取mapTask的执行进度,当获取MapTask执行完成的时候就会开启多线程对map的输出文件进行拷贝。拷贝的时候是按分区进行拷贝的。对应的ReduceTask会将对应的Maptask的输出文件的对应分区的文件进行拷贝
⑦由于ReduceTask要针对所有的MapTask的输出文件,所以拷贝过来的文件是所有mapTask的输出的对应分区的文件,将从各个mapTask拷贝过来的对应分区文件进行文件的归并和排序
⑧归并完成后会调用GroupComoparator进行分组读取给自定义reduce函数,所以reduce函数拿到的就是一组组的数据(key相同的为一组)
⑨按照自己定义的reduce逻辑进行执行
⑩最终结果输出到hdfs