MapReduce工作流程
1.由程序内的InputFormat(默认实现类TextInputFormat)来读取外部数据,它会调用RecordReader(它的成员变量)的read()方法来读取,返回k,v键值对。
2.读取的k,v键值对传送给map()方法,作为其入参来执行用户定义的map逻辑。
3.context.write方法被调用时,outputCollector组件会将map()方法的输出结果写入到环形缓冲区内。
4.环形缓冲区其实就是一个数组,后端不断接受数据的同时,前端数据不断被溢出,长度用完后读取的新数据再从前端开始覆盖。这个缓冲区默认大小100M,可以通过MR.SORT.MB(应该是它)配置。
5.spiller组件会从环形缓冲区溢出文件,这过程会按照定义的partitioner分区(默认是hashpartition),并且按照key.compareTo进行排序(底层主要用快排和外部排序),若有combiner也会执行combiner。spiller的不断工作,会不断溢出许多小文件。这些文件仍在map task所处机器上。
6.小文件执行merge(合并),行程分区且区内有序的大文件(归并排序,会再一次调用combiner)。
7.Reduce会根据自己的分区,去所有map task中,从文件读取对应的数据。
1.ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中。在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。
2.按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。
3.reduce()函数将计算结果写到HDFS上。
就此mapreduce的工作结束,其中map的context.write()调用后,开始聚合数据写入到reduce的过程叫做Shuffle,是mapreduce的核心所在。