我的印象是组合器就像作用于本地映射任务的减速器一样,即它聚合单个映射任务的结果以减少输出传输的网络带宽。
并且从阅读中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 不保证是否会调用组合器。但是当我打开归约阶段时,组合器就会被调用。
为什么会出现这种行为?
现在当我读到第 6 章(第 208 页)时how MapReduce works
。我看到这一段描述在Reduce side
.
如果map输出足够小,则它们会被复制到reduce任务JVM的内存中(缓冲区的大小由mapred.job.shuffle.input.buffer.percent控制,它指定用于此目的的堆的比例);否则,它们将被复制到磁盘。当内存缓冲区达到阈值大小(由mapred.job.shuffle.merge.percent控制)或达到映射输出的阈值数量(mapred.inmem.merge.threshold)时,它将被合并并溢出到磁盘。如果指定了组合器,它将在合并期间运行,以减少写入磁盘的数据量。
我从这一段中得出的推论是:
1) 合路器是ALSO在减少阶段运行。