1.6 MapReduce
数据流的概念和技术,虽然在程序的模块化和可重用(可重复使用)方面也有很大的意义,但主要还是由于提高并行度的要求而出现的,是并行处理的一种重要方法。前面讲过,如果考虑作为输入数据的样本数量和所进行的计算操作这两个因素,有些问题是小数据大计算,有些则是大数据小计算。当然,还有小数据小计算和大数据大计算两种可能,前者不足挂齿,后者则当然更具挑战性。但是,对于大数据,“化整为零,分而治之”的策略总是不错的,更何况大数据中的数据本来就可能是“零”的而不是“整”的。但是一般而言,“分”也不是一分了之,最后还得汇总。所以,应该是先分头处理,然后对结果加以整合。按这样的思路设计的数据流模型,就称为MapReduce,意为先Map然后Reduce,其结构和拓扑如图1-4所示。
在这种模型中,输入数据被分成N份,分别由N个实施Map计算的Mapper节点分头加以处理,处理的结果由M个实施Reduce计算的Reducer节点加以汇总。在实际使用中,M常常是1,即只有一个节点进行Reduce计算。什么叫Map计算呢?实际上就是某种函数的Lambda计算。Map这个词,一方面来自Lambda计算的理论,另一方面函数的本意就是映射。一般而言,Map计算不一定显著减少数据的数量,往往是有多少输入就有多少输出(但是内容变了)。而Reduce计算则是整合和汇总,其一般会把数据的数量大大减少下来,所以叫Reduce。可见,这里的假设是数据互相独立,并行度仅存在于数据(样本)之间。
图1-4 MapReduce拓扑图
这样的并行处理实在是太简单了,这样的办法谁都能想到,简直是简易得令人不好意思提起,以至于人们称之为“embarrassingly parallel”,意为简单到令人尴尬的并行处理。不过,模型固然简单,但要真正把它实现出来也并非易事。
既然MapReduce这个模型很简单,当然不会是到了最近才有人想起而突然发明出来的,而是早已有之。但是为什么它一直悄无声息,到现在才一下子大热起来呢?因为以前人们想用并行处理解决的大多是小数据大计算的问题,那些问题的输入数据量并不很大,但是算法却相当复杂,或者数据之间互相牵连,少有能将它们分头加以处理的算法,总之是都不太适合用MapReduce的模型加以并行处理的。而有些适合用MapReduce解决的问题,则数据量还不大,那时候也还没有“精准营销”一类的概念和要求。是互联网的出现和发展使情况发生了变化,因互联网而来的许多活动产生了大量的数据,而且需要对每份数据进行的计算大多并不复杂,互相的牵连往往也不多,从而就催生了许多属于大数据小计算且适合用MapReduce模型加以解决的问题。再说,计算机技术的发展也使得采用大规模集群进行计算的成本大大降低而变得可行。近年来大数据技术,特别是MapReduce技术成为热门技术,正是这些因素综合作用的结果。
在MapReduce模型中,Map阶段的并行度一般是比较高的,Mapper节点的数量N远大于Reducer节点的数量M。这样,Map阶段的并行度至少就是N,而整体上是否能比N更高则取决于Map和Reduce这两个阶段之间是否有并行,Reducer节点在Map阶段是否空闲。如果Mapper与Reducer之间是数据流的关系,即Mapper节点一边处理一边就把结果发送给Reducer,使其可以同时进行处理,那么Map阶段的并行度甚至可以达到N+M。而如果Mapper与Reducer之间是工作流的关系,则M个Reducer节点在Map阶段只能等待,并行度就会下降一些。
Map阶段结束之后,如果Mapper与Reducer之间是个均匀的数据流,而且节点负载得到均衡,那就没有明显的Reducer阶段了,因为在Map计算的同时Reduce计算也在进行,到Map阶段结束的时候Reduce也基本完成了。但是,如果两种计算的负载达不到均衡,或者Mapper与Reducer之间干脆是工作流的关系,那么Map阶段结束之后还会有一个Reduce阶段,此时的并行度为M,因为N个Mapper节点此时都使不上劲了。
最后还要再次强调指出,并非所有的大数据问题都适合用MapReduce解决。