map方法输出的键值对,会被搜集进环形缓冲区。环形缓冲区是内存中的一个字节数组,默认的大小是100M。
当环形缓冲区中被写入了80%的数据的时候,会将这80%的部分进行分区、排序,并溢写到磁盘,生成一个文件。在这个过程中,如果上游还有数据产生,将存储在剩余的20%的空间内。如果上游产生数据的速度非常快,剩余的20%也被填充满,并且80%的数据还没有溢写完成,此时任务将阻塞,上游不再读取数据,直到溢写文件完成。最终可能会生成多个溢写的磁盘文件。
将每一个溢写的磁盘文件合并成为一个文件,在合并的过程中,依然会按照分区、Key进行排序。最终,每一个MapTask生成一个磁盘文件。至此,MapTask执行结束。
每一个ReduceTask需要去处理一个分区的数据,因此ReduceTask需要到每一个MapTask所在的节点去fetch自己分区的数据。
拉取到的数据,如果比较小,会直接保存在内存中,在内存中完成排序,直到达到内存阈值,将其溢写到文件中;如果比较大,会直接以文件的形式保存起来。
数据拉取完成后,会按照设定好的合并因子进行合并。
按照Map阶段输出的的键进行分组,将相同键所对应的所有的值聚合到一起,形成一个集合。
将最终的结果,由客户端指定的OutputFormat进行输出。至此ReduceTask结束。