本节书摘来异步社区《Hadoop MapReduce实战手册》一书中的第1章,第1.4节,作者: 【美】Srinath Perera , Thilina Gunarathne 译者: 杨卓荦 责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.4 给WordCount MapReduce程序增加combiner步骤
Hadoop MapReduce实战手册
运行map函数后,如果有许多键值对使用相同的键,那么Hadoop必须将所有这些值传送到reduce函数。这可能会产生一个非常显著的开销。为了优化这样的场景,Hadoop支持一个专门的函数——combiner。如果配置了combiner,Hadoop会在运行完成mapper之后、调用reducer之前,在map节点所在的那个节点调用combiner。这可以显著地减少传输到reduce步骤的数据量。
本节将说明如何在1.3节介绍的WordCount示例程序中使用combiner。
操作步骤
现在,让我们加入combiner配置来运行MapReduce作业。
1. combiner必须和reduce函数具有相同的接口。对于WordCount示例程序,我们将会复用
reduce函数作为combiner。
2. 为了让MapReduce作业使用combiner,需要在示例程序中取消//job.setCombinerClass.
(IntSumReducer.class);这行的注释,然后重新编译代码。
3. 将hadoop-cookbook-chapter1.jar文件复制到HADOOP_HOME目录,并且用前一节介绍的方式运行WordCount。确保运行作业之前删除了旧的输出目录。
4. 最终结果会放在output目录下。
工作原理
要激活combiner,用户应该提供mapper、reducer和combiner作为MapReduce作业的输入。在该环境中,一旦mapper函数执行完成,Hadoop就在mapper函数所在的节点上执行combiner。使用这种方法,combiner可以预先处理mapper所产生的数据,然后再将结果发送给reducer,从而减少转移的数据量。
例如,WordCount示例,combiner从map步骤接收多个(word, 1)对作为输入,并输出一个(word, N)对。例如,如果输入文档中单词“the”出现了10 000次,那么mapper将产生10 000个(the, 1)对,而combiner将只产生一个(the, 10,000),从而减少传输给reduce任务的数据量。
然而,combiner只适用于满足代数交换律和结合律的函数。例如,同样的思路对计算平均值就会无效。由于平均值是不满足交换律和结合律的,在这种情况下,combiner将会得到一个错误的结果。
更多参考
虽然在示例程序中,我们是复用reduce函数实现的combiner功能,你也可以写自己的combiner函数,就像我们在前一节中介绍的map和reduce函数。然而,combiner函数的签名必须与reduce函数的签名完全一致。
在本地配置Hadoop的情况下,使用combiner不会产生显著的收益。然而,如1.8节所述,在分布式的集群环境中,combiner可以提供显著的收益。