集群上的可用带宽限制了MapReduce作业的数量,因此尽量避免map和reduce任务之间的数据传输是有利的。Hadoop允许针对map任务的输出指定一个combiner(就像mapper和reducer一样),combiner函数的输出作为reduce函数的输入。由于combiner属于优化方案,所以Hadoop无法确定要对一个指定的map任务输出记录调用多少次combiner(如果需要)。换而言之,不管调用combiner多少次,0次、1次或多次,reducer的输出结果都是一样的。
combiner的规则制约着可用的函数类型。这里举例说明,假设要计算1950年的最高气温,由两个map任务处理。第一个map的输出如下:
(1950, 0)
(1950, 20)
(1950, 10)
第二个map输出如下:
(1950, 25)
(1950, 15)
reduce函数被调用时,输入如下:
(1950, [0, 20, 10, 25, 15])
因为25为该列数据中最大的,所以它的输出如下:
(1950, 25)
我们可以像使用reduce函数那样,使用combiner找出每个map任务输出结果中的最高气温。如此一来,reduce函数调用时将被传入以下数据:
(1950, [20, 25])
reduce输出的结果和以前一样。更简单地说,我们可以通过下面的表达式来说明气温数值的函数调用:
max(0, 20, 10, 25, 15)=max(max(0, 20, 10), max(25, 15))=max(20, 25)=25
并非所有函数都具有该属性。例如,如果我们计算平均气温,就不能用求平均函数mean作为我们的combiner函数,因为:
mean(0, 20, 10, 25, 15)=14
但是:
mean(mean(0, 20, 10), mean(25, 15))=mean(10, 20)=15
combiner函数不能取代reduce函数。为什么呢?我们仍然需要reduce函数来处理不同map输出中具有相同键的记录。但combiner函数能帮助减少mapper和reducer之间的数据传输量,因此,单纯就这点而言,在MapReduce作业中是否使用combiner函数还是值得斟酌的。
完毕。