我调整了标准字数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时,这会导致奇怪的行为。计数器不是接收减少输入组/减少输出记录的值,而是接收减少输入组和减少输入记录的总和,即唯一字加上总字或键加值。
任何人都可以帮助我理解为什么会发生这种情况的逻辑吗?根据我的理解(可能是错误的),如果有任何事情减少了给定的数量,那么这样做。
以下是一个例子:
假设我们有两个文件file1和file2。
File1包含:word1 word2 word3 word1
File2包含:word1 word2
映射后,我们从两个映射函数(每个文件一个)获得以下输出:
对于file1:word1,1 word2,1 word3,1 word1,1
对于file2:word1,1 word2,1
然后使用与减速器功能相同的组合器将它们组合。键值对变为:
对于file1:word1,2 word2,1 word3,1
File2保持不变。 reducer适用于每个,所以我们将有3个reducer函数(每个单词一个)来获得总计数。您面临的问题是,如果计数器在reducer&combiner阶段递增,则计数器对于file1和file2中的每个字递增,然后计数器在每个字的reduce阶段递增(减少函数调用) )。作为组合器的重点是为特定文件组合相同的键(而不是跨多个文件的所有键)。计数器不应在组合器阶段递增。
你正在做的是:地图阶段:计数器= 0合并阶段:在文件1:计数器= 4在文件2:计数器=上一个值+ 2合并后阶段值为6.减少阶段:对于每个密钥计数器增加。因此,计数器变为9。
希望能解决你的问题。