1.9 Hadoop的MapReduce计算框架
如上所述,Hadoop是个面向MapReduce的大数据处理平台,为MapReduce计算提供了一个框架。这是什么意思呢?打个比方:Hadoop就好像一块印刷电路板,上面什么都连好了,就留出两个芯片插座,一个用来插Mapper芯片,一个用来插Reducer芯片。使用者自带这两种芯片,在电路板上插上你的Mapper和Reducer,再设置好参数,即Mapper要复制几份、Reducer要复制几份,然后一按电钮,机器就运转了。这个假想的电路板就起着“框架”的作用。框架是固定的,而Mapper和Reducer则是可更换的。
也就是说,数据流的拓扑是在框架中固定连接好的,那就是链状的MapReduce,但是采用什么具体的Mapper和Reducer则留待实际使用的时候才确定,而且各自的并行度可以设置。用前面打过的一个比方就是:Mapper和Reducer都画在透明胶片上,在Mapper的位置上可以是N块胶片叠合,Reducer的位置上可以是M块胶片叠合,但是我们眼睛所见的就只有两个节点,就是Mapper和Reducer。
不过,使用者虽然可以指定有几份Mapper和几份Reducer,却不能严格指定将它们放在哪些节点上,Hadoop会根据输入数据所在的地点和相关节点的负载情况自动加以安排。
使用者自带的“芯片”可以是外购的,也可以是自己开发的。Hadoop为此提供了一个Mapper类和一个Reducer类,插到这框架上的必须是对这两个类的继承和扩充。
说是两个类,其实起关键作用的就是两个方法函数,即map()和reduce(),这就是系统应用层的核心所在。这两个函数所做的计算,按理说都是Lambda演算,不过在函数中不需要像在Unix的那些utility中一样写上while循环。当然,既然是Lambda演算,while循环还必须要,但那是由框架提供的,Mapper节点和Reduce节点上的Hadoop框架会各自循环调用map()和reduce()。另外,数据流中每个节点的输入端还必须有一个队列,用来吸收上下游节点之间的速度差异和波动。在MapReduce这个模型中,其实只有Reduce节点才有这个需要,所以Hadoop的MapReduce框架也为Reduce节点提供输入队列。
数据流的关键之一是数据怎么在节点之间流通。从逻辑上看,MapReduce这个模型中的数据流通都是单向的,都是从Mapper的输出端流到Reducer的输入端(要不然就不叫有向无环图了)。不过这只是就应用层而言,在传输层和网络层当然会有双向的握手,Hadoop会在Mapper与Reducer之间建立起TCP连接,上下游节点之间在传输层以TCP报文为单位,在网络层则以IP包为单位传输数据。
下一个问题是权衡数据传输的粒度,粒度太小则开销太大,粒度太大则上下游的并行度可能会降低,且实时性变差。进一步,如果上下游之间有排序,则如前所述数据流将变成工作流,那就变成了批处理,完全丧失了实时性。可是排序对于许多MapReduce计算也确实是需要的,即使为此而丧失了实时性,对于许多大数据处理的工作而言很可能也还是值得的。OLAP (在线分析处理)不同于OLTP(在线业务处理),对OLAP的计算本来就并无实时要求,并且往往要把同一批输入数据翻来覆去地梳理挖掘好多遍,而Hadoop的设计目标恰恰就是用于OLAP。至于并行度的降低,则由于Mapper节点与Reducer节点的数量之比常常会很大,所以在map阶段让Reducer节点空闲也没有多大影响,而Reducer阶段的计算则通常都很简单(只是汇总一下),应该不会占很长时间。
这样权衡下来,Hadoop的设计者选择了在框架中自动提供对于Mapper输出数据的排序。其实Hadoop在这个问题上还是为使用者提供了一定的灵活性,框架上的这一大块部件(软件)是可以被替换的,只是用户需要自己开发这样的替代品,实际上好像也没听说有人这样做。
Hadoop平台运行在集群上,但一般并不是举整个集群之力来进行仅仅一个MapReduce作业的计算,而是像在分时系统上那样,可以同时在集群上进行多个作业的计算,这些作业之间既可能是并行的,也可能是并发的。具体到其中的某个节点机,也完全可以并发地执行分属于不同作业的进程。在这个方面,整个集群、整个平台作为一个整体的表现与单机上的分时系统是很相似的。所以,如果某个特定MapReduce作业中的Reduce节点空闲着,并不意味着其所在的那台机器是在空转,因为它也许正在忙于别的什么作业的map()计算或reduce()计算。
在Hadoop的2.0版之前,对于作业的管理是集中的,有个中央集权的Jobtracker在主节点上统管着平台上所有的MapReduce作业,包括作业的部署、启动和进度。这对于规模较小的计算平台是合适的,但是当平台的规模变得很大的时候就不合适了。所以2.0版以后的Hadoop采用一种称为YARN的机制,主节点接受一个作业之后就选择一个普通节点,或曰“从节点”,在这节点上成立对于这个作业的管理机构,再由这管理机构操办和管理这个作业的运行,而主节点则腾出手来专管资源分配。这样就把对于作业的投运和管理也分布出去了。所以主节点的名称以前叫Jobtracker,而现在叫ResourceManager。
除传统的MapReduce之外,新版的Hadoop还允许用Unix/Linux那些现成的Utility程序,即/bin等目录下那些工具软件搭建链状数据流,其每个逻辑上的节点都可以是分布的,就像Mapper一样有很多份,由很多物理节点并行分担所需的计算。这样就既可以发掘出上下游之间的并行度,又可以发掘出数据之间的并行度。