我的印象是,combiner 就像作用于本地 map 任务的 reducer,即它聚合单个 Map 任务的结果,以减少输出传输的网络带宽。
从阅读来看Hadoop- The definitive guide 3rd edition
,我的理解似乎是正确的。
来自第 2 章(第 34 页)
组合器功能 许多 MapReduce 作业受到集群上可用带宽的限制,因此尽量减少在 map 和 reduce 任务之间传输的数据是值得的。Hadoop 允许用户指定在映射输出上运行的组合器函数——组合器函数的输出形成reduce 函数的输入。由于组合器功能是一种优化,Hadoop 不保证它会为特定的地图输出记录调用多少次(如果有的话)。换句话说,调用组合函数零次、一次或多次应该从减速器产生相同的输出。
所以我在字数问题上尝试了以下方法:
job.setMapperClass(mapperClass);
job.setCombinerClass(reduceClass);
job.setNumReduceTasks(0);
这是计数器:
14/07/18 10:40:15 INFO mapred.JobClient: Counters: 10
14/07/18 10:40:15 INFO mapred.JobClient: File System Counters
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of bytes read=293
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of bytes written=75964
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of read operations=0
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of large read operations=0
14/07/18 10:40:15 INFO mapred.JobClient: FILE: Number of write operations=0
14/07/18 10:40:15 INFO mapred.JobClient: Map-Reduce Framework
14/07/18 10:40:15 INFO mapred.JobClient: Map input records=7
14/07/18 10:40:15 INFO mapred.JobClient: Map output records=16
14/07/18 10:40:15 INFO mapred.JobClient: Input split bytes=125
14/07/18 10:40:15 INFO mapred.JobClient: Spilled Records=0
14/07/18 10:40:15 INFO mapred.JobClient: Total committed heap usage (bytes)=85000192
这是part-m-00000
:
hello 1
world 1
Hadoop 1
programming 1
mapreduce 1
wordcount 1
lets 1
see 1
if 1
this 1
works 1
12345678 1
hello 1
world 1
mapreduce 1
wordcount 1
所以很明显没有应用组合器。我知道 Hadoop 不保证是否会调用组合器。但是当我打开 reduce 阶段时,组合器会被调用。
为什么会出现这种行为?
现在,当我阅读第 6 章(第 208 页)时how MapReduce works
。我看到这一段描述在Reduce side
.
如果映射输出足够小,则将其复制到 reduce 任务 JVM 的内存(缓冲区的大小由 mapred.job.shuffle.input.buffer.percent 控制,它指定用于此目的的堆的比例);否则,它们将被复制到磁盘。当内存缓冲区达到阈值大小(由 mapred.job.shuffle.merge.percent 控制)或达到映射输出的阈值数量(mapred.inmem.merge.threshold)时,它被合并并溢出到磁盘。如果指定了组合器,它将在合并期间运行以减少写入磁盘的数据量。
我从这一段的推论是:1)组合器也在减少阶段运行。