MapReduce运行阶段数据传递经过输入文件、Map阶段、中间文件、Reduce阶段、输出文件五个阶段,用户程序只与Map阶段和Reduce阶段的Worker直接相关,其他事情由Hadoop平台根据设置自行完成。
从用户程序User Program开始,用户程序User Program链接了MapReduce库,实现了最基本的map函数和reduce函数。
(1)MapReduce库先把User Program的输入文件划分为M份,如上图,将数据分成了分片0~4,每一份通常为16MB~64MB;然后使用fork将用户进程复制到集群内其他机器上。
(2)User Program的副本中有一个Master副本和多个Worker副本。Master是负责调度的,为空闲Worker分配Map作业或者Reduce作业。
(3)被分配了Map作业的Worker,开始读取对应分片的输入数据,Map作业数量与输入文件划分数 M相同,并与分片一一对应;Map作业将输入数据转化为键值对表示形式并传递给map函数,map函数产生的中间键值对被缓存在内存中。
(4)缓存的中间键值对会被定期写入本地磁盘,而且被划分为R个区(R的大小是由用户定义的),每个区会对应一个Reduce作业;这些中间键值对的位置会被通报给Master,Master负责将信息转发给Reduce Worker。
(5)Master通知分配了Reduce作业的Worker负责数据分区,Reduce Worker读取键值对数据并依据键排序,使相同键的键值对聚集在一起。同一个分区可能存在多个键的键值对,而reduce函数的一次调用的键值是惟一的,所以必须进行排序处理。
(6)Reduce Worker遍历排序后的中间键值对,对于每个唯一的键,都将键与关联的值传递给reduce函数,reduce函数产生的输出会写回到数据分区的输出文件中。
(7)当所有的Map和Reduce作业都完成了,Master唤醒User Program,MapReduce函数调动返回User Program。
执行完毕后,MapReduce的输出放在R个分区的输出文件中,即每个Reduce作业分别对应一个输出文件。用户可将这R个文件作为输入交给另一个MapReduce程序处理,而不需要主动合并这R个文件。在MapReduce计算过程中,输入数据来自分布式文件系统,中间数据放在本地文件系统,最终输出数据写入分布式文件系统。
必须指出Map或Reduce作业和map或reduce函数存在以下几个区别:
①Map或Reduce作业时从计算框架的角度来认识的,而map或reduce函数是需要程序员编写代码完成的,并在运行过程中被对用Map或Reduce作业调度;
②Map作业处理一个输入数据的分片,可能需要多次调用map函数来处理输入的键值对;
③Reduce作业处理一个分区的中间键值对,期间要对每个不同的键调用一次reduce函数,一个Reduce作业最终对应一个输出文件。