在执行map任务时首先对该任务处理的文件段进行读入,在处理完毕后,该Job中没有设置Reduce任务,则直接把该任务所处理文件段数据的结果写入到HDFS中该Job的output目录下,output目录由用户在任务提交前通过参数mapred.output.dir指定。
如果该Job中存在Reduce任务,则把结果key默认按照reduce任务个数进行hash方式取余确定放在哪个分区中,到Reduce阶段,Reduce任务取属于该任务分区的数据进行reduce操作。
如果Map阶段有指定的combiner,则对map的结果做combine操作,combine通常与Reduce操作相同,对map的结果先做一次reduce,会减少map向reduce传输数据量。
Map对最终写入的数据需要对相同分区的数据放在一起,并且相同分区的数据需要按照key的顺序排放,其过程如下:
1. 先把key、value数据放在划分的固定大小的内存中
2. 等到该内存达到使用的阈值时,把内存中的数据按照分区,key的顺序存到文件中,并记录该文件中各个分区数据起始位置的索引值。
3. 在从内存输出到文件时,如果存在combine,则对内存中数据先做一次combine。
4. 重复循环第二,第三步,最终把所有结果存放在不同的文件中(每次从内存转到文件时输出为一个独立文件)。
5. 然后对不同文件的结果进行分区的合并,并且对同一分区的数据进行重新排序,最终结果输出到一个文件中,并记录该文件中各个分区数据起始位置的索引值。
内存中存放key,value的数据结构:
在内存中一对key和value就是一条记录,kvoffsets[]数组的长度就是能存放的最大记录个数,存放的是某条记录在kvbuffer[]的信息,如上图中kvoffsets数组下标3中存放的数据就是第三条记录在