第3章 MapReduce编程模型

MapReduce应用广泛的原因之一在于它的易用性。它提供了一个因高度抽象化而变得异常简单的编程模型[1]。在第2章中,我们已经对该编程模型的定义以及应用场景做了简单介绍。在这一章中,我们将从Hadoop MapReduce编程模型实现的角度对其进行深入分析,包括其编程模型的体系结构、设计原理等。

本章不介绍Hadoop MapReduce API的使用方法,而是从实现角度介绍其设计方法。

3.1 MapReduce编程模型概述

在第2章中,我们提到MapReduce是在总结大量应用的共同特点的基础上抽象出来的分布式计算框架,它适用的应用场景往往具有一个共同的特点:任务可被分解成相互独立的子问题。基于该特点,MapReduce编程模型给出了其分布式编程方法,共分5个步骤:

1)迭代(iteration)。遍历输入数据,并将之解析成key/value对。

2)将输入key/value对映射(map)成另外一些key/value对。

3)依据key对中间数据进行分组(grouping)。

4)以组为单位对数据进行归约(reduce)。

5)迭代。将最终产生的key/value对保存到输出文件中。

MapReduce将计算过程分解成以上5个步骤带来的最大好处是组件化与并行化。

为了实现MapReduce编程模型,Hadoop设计了一系列对外编程接口。用户可通过实现这些接口完成应用程序的开发。

3.1.1 MapReduce编程接口体系结构

MapReduce编程模型对外提供的编程接口体系结构如图3-1所示,整个编程模型位于应用程序层和MapReduce执行器之间,可以分为两层。第一层是最基本的Java API,主要有5个可编程组件,分别是InputFormat、Mapper、Partitioner、Reducer和OutputFormat[2]。Hadoop自带了很多直接可用的InputFormat、Partitioner和OutputFormat,大部分情况下,用户只需编写Mapper和Reducer即可。第二层是工具层,位于基本Java API之上,主要是为了方便用户编写复杂的MapReduce程序和利用其他编程语言增加MapReduce计算平台的兼容性而提出来的。在该层中,主要提供了4个编程工具包。

第3章 MapReduce编程模型 - 图1

图 3-1 MapReduce编程接口体系结构

❑JobControl:方便用户编写有依赖关系的作业,这些作业往往构成一个有向图,所以通常称为DAG(Directed Acyclic Graph)作业,如第2章中的朴素贝叶斯分类算法实现便是4个有依赖关系的作业构成的DAG。

❑ChainMapper/ChainReducer:方便用户编写链式作业,即在Map或者Reduce阶段存在多个Mapper,形式如下:


[MAPPER+REDUCER MAPPER*]


❑Hadoop Streaming:方便用户采用非Java语言编写作业,允许用户指定可执行文件或者脚本作为Mapper/Reducer。

❑Hadoop Pipes:专门为C/C++程序员编写MapReduce程序提供的工具包。

[1]关于MapReduce编程模型的数学基础,可参考Ralf Lammel的论文“Google’s MapReduce Programming Model—Revisited”。

[2]还有一个组件是Combiner,它实际是一个Reducer。