Hadoop Mapreduce(Java) - 使用Reducer as Combiner计算文本中所有唯一单词的错误

时间:2018-04-22 15:34:21

标签: java mapreduce hadoop2

我调整了标准字数Hadoop示例,使用用户定义的计数器计算一系列输入文本文件中的所有唯一字,并在驱动程序类中定义枚举,如下所示:

public enum Operations { UNIQUE_WC }

我在Reducer中的代码如下:

public class WordCountReducer extends Reducer <Text, IntWritable, Text, IntWritable> {

private IntWritable result = new IntWritable();

public void reduce(Text key, Iterable<IntWritable> values, Context context) 
   throws IOException, InterruptedException {
   int sum = 0;

   for (IntWritable val : values) {
        sum += val.get();
    }

   result.set(sum);
   context.write(key, result);    
   context.getCounter(WordCountJobControl.Operations.UNIQUE_WC).increment(1);
    }
}

当Reducer类设置为Combiner时,这会导致奇怪的行为。计数器不是接收减少输入组/减少输出记录的值,而是接收减少输入组和减少输入记录的总和,即唯一字加上总字数或键加值。

任何人都可以帮助我理解为什么会发生这种情况的逻辑吗?根据我的理解(可能是错误的),如果有任何事情减少了计数,那么这样做。

1 个答案:

答案 0 :(得分:0)

以下是一个示例:

假设我们有两个文件file1和file2。

File1包含: word1 word2 word3 word1

File2包含: word1 word2

映射后,我们从两个映射函数(每个文件一个)获得以下输出:

对于文件1: word1,1
word2,1
word3,1
word1,1

对于文件2: word1,1
word2,1

然后使用与减速器功能相同的组合器将其组合。键值对变为:

对于文件1: word1,2
word2,1
word3,1

File2保持不变。每个应用减速器,因此我们将有3个减速器功能(每个单词一个)以获取总计数。您面临的问题是,如果计数器在reducer&Combiner阶段递增,则计数器针对file1和file2中的每个单词递增,然后计数器又在reduce阶段针对每个单词递增(reduce函数调用)。关键是合并器可以为特定文件组合相同的键(而不是多个文件中的所有键)。在组合器阶段不应增加计数器。

您正在做的是: 地图阶段:计数器= 0 合并阶段: 在文件1:Counter = 4 在文件2:Counter =先前值+2 合并后的阶段值为6。 减少阶段: 对于每个键计数器都会增加。因此计数器变为9。

希望可以解决您的问题。