在前面的一系列文章中我主要围绕Hadoop对Map任务执行框架的设计与实现展开了详细的讨论,记得在博文Hadoop中Map任务的执行框架( 见 )中说过还要为大家详细地描述Hadoop对Reduce任务执行框架的设计,那么在本文,我将兑现这个承诺。
其实,Hadoop中Reduce任务执行框架跟它的Map任务执行框架大致是很相似的,唯一的不同之处就是他们的数据输入来源、数据输出目的地不一样而已。总的说来,Map任务的输入数据来源于HDFS,最后的结果输出分布在每一个执行map任务的机器节点本地文件系统上,而Reduce任务的数据来源于每一个执行map任务的机器节点本地文件系统,它的最终结果存放在作业设置的HDFS某个目录下。
在这里我想简单的讨论一下为什么map任务的输出要保存到各自执行节点的本地文件系统,而不是hadoop所依赖的某一个分布式文件系统(如HDFS)?现在假如说map任务的结果输出被保存到了HDFS上了,这样的话,所有的map输出就在网络上移动了一次,当开始执行某一个reduce任务的时候,它会从HDFS上去取输入数据,尽管Hadoop的任务调度器总是最大努力将reduce任务交给有map输出结果的机器节点(也就是执行过它的map任务的机器节点),但在绝大多数情况下总会存在一些reduce任务需要的输入数据有部分不再本地,从而去HDFS上取,最后导致有些map任务的输出结果在网络上移动了两次;如果将map任务的输出结果就放在它的本地文件系统,那么当某一个reduce开始执行之前,它需要从每一个机器节点的本地文件系统上取属于它的map输出数据,最终所有的map结果数据在网络上只移动了一次。同时,在这里就可以解释为什么要在map任务中进行合并,对map的输出进行合并可以大大较少最后的输出,一方面减轻了reduce的工作负载,另一方面也减少了reduce执行时数据移动的消耗。
还是来看看Hadoop是如何来设计Reduce任务执行框架的:
关于Hadoop的Reduce任务执行框架的具体流程大体同Map,在这里我就不再赘述了,有兴趣的盆友可以参看我的另一篇博文:Hadoop中Map任务的执行框架。不过,与Map略微的不同之处就是构造数据记录读取器的数据来源,reduce需要先从其它机器节点的本地文件系统中copy下来,至于reduce是如何copy这些数据的,这其中又用了什么网络协议,我会在以后的文章中作详细的阐述,不过有一点我提一下,reduce从map节点copy下来的数据会根据当前节点的内存情况把它们放到内存或本地磁盘中。
到这里,我已经分析了Hadoop中整个Map-Reduce模型的设计,现在我先把这两个模型组合起来,好让大家能够跟清楚地了解Hadoop是如何对一个提交的作业进行map-reduce处理的。这个演示过程如下: