我调整了标准字数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时,这会导致奇怪的行为。计数器不是接收减少输入组/减少输出记录的值,而是接收减少输入组和减少输入记录的总和,即唯一字加上总字数或键加值。
任何人都可以帮助我理解为什么会发生这种情况的逻辑吗?根据我的理解(可能是错误的),如果有任何事情减少了计数,那么这样做。
答案 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。
希望可以解决您的问题。