【发布时间】:2014-07-18 17:46:38
【问题描述】:
我的印象是,combiner 就像是作用于本地 map 任务的 reducer,即聚合单个 Map 任务的结果,以减少输出传输的网络带宽。
通过阅读Hadoop- The definitive guide 3rd edition,我的理解似乎是正确的。
来自第 2 章(第 34 页)
组合函数 许多 MapReduce 作业受到集群上可用带宽的限制,因此尽量减少在 map 和 reduce 任务之间传输的数据是值得的。 Hadoop 允许用户指定在 map 输出上运行的组合器函数——组合器函数的输出形成 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 阶段时,组合器会被调用。
为什么会这样?
现在,当我在how MapReduce works 上阅读第 6 章(第 208 页)时。我看到Reduce side中描述的这一段。
如果映射输出足够小,则将其复制到 reduce 任务 JVM 的内存(缓冲区的大小由 mapred.job.shuffle.input.buffer.percent 控制,它指定要使用的堆的比例以此目的);否则,它们将被复制到磁盘。当内存缓冲区达到阈值大小(由 mapred.job.shuffle.merge.percent 控制)或达到映射输出的阈值数量(mapred.inmem.merge.threshold)时,它被合并并溢出到磁盘。如果指定了组合器,它将在合并期间运行以减少写入磁盘的数据量。
我从这一段的推论是: 1) Combiner ALSO 在 reduce 阶段运行。
【问题讨论】: