shuffle的主要职责是将map任务产生的输出,按照partitioner组件制定的规则,分发给reduce任务。
主要分为3个过程,map端的spill过程,reduce端的copy和sort过程。
1.spill过程
map任务不断地以<K,V>对的形式把结果输出到内存的一个数据结构中,这个数据结构叫Kvbuffer,是一个字节数组。
Kvbuffer不仅存数据,也保存对应的索引,其上有一个分界点,初始是0(之后会改变,如何改变接下来进行介绍)。数据的存储方向是自分界点向上增长,索引是自分界点向下增长。
当Kvbuffer中的空间不够用了,就将内存中的数据溢写到磁盘,这个过程叫做spill。
spill按照partiton值和key两个关键字对Kvbuffer排序。排序后,在本地磁盘中建立spill12.out的文件,spill线程按照partition顺序把内存中的数据溢写到磁盘上。也会产生spill12.out.index文件存储索引数据,这个索引文件如果能放在内存上就放在内存上,内存不够存在就放在磁盘上。
当进行spill过程时,map任务不会停止,将继续输出数据到kvbuffer上,这时临界点会改变,将剩余空间的中点作为新的临界点。(如果不改变临界点,数据和索引数据很快就会碰头)
当map输出数据很多,产生多个spill文件,需要对这些文件进行merge。merge过程创建一个叫file.out的文件和一个叫file.out.Index的文件用来存储最终的输出和索引。
2.copy过程
Reduce任务通过HTTP向各个Map任务拖取它所需要的数据。
3.merge sort
Reduce是一边copy一边sort,即copy和sort两个阶段是重叠而不是完全分开的。