我目前正在开发一个Java EMR项目,其中我的密钥由2个文本组成。 我在我的一个步骤中设置了NaturalKeyGroupingComparator,仅比较密钥的左侧部分。
现在这是Reducer的Java代码:
public void reduce(Pair key, Iterable<Data> values, Context context) throws IOException, InterruptedException{
int totalOccurrences=0;
for (Data value : values){
if (key.getRight().toString().equals("*")){
totalOccurrences+=value.getOccurrences();
}
else{
value.setCount(new IntWritable(totalOccurrences));
}
}
}
现在一切都按照计划完美地完成了,但我不明白究竟发生了什么。 如何在reduce运行的中间改变键?
答案 0 :(得分:2)
你的问题是一个很好的初学者问题:)
我已经写过here。
我想要记住的最重要的事情是Iterable 没有集合支持,它是在调用next()方法时动态计算的。请记住这一点。
如果您想要查看代码类型的人,请完成以上帖子。
//行号157
if (hasMore) {
nextKey = input.getKey();
nextKeyIsSame = comparator.compare(currentRawKey.getBytes(), 0,
currentRawKey.getLength(),
nextKey.getData(),
nextKey.getPosition(),
nextKey.getLength() - nextKey.getPosition()
) == 0;
} else {
nextKeyIsSame = false;
}
的摘录
每次调用该方法,你调用next(),它基本上检查键是否在底层流中发生变化,如果不是它只是传递给你下一个值(记住键是有序的),否则它安排调用reducer方法再次使用新密钥并可迭代。
底层流始终是一个键值对,ReducerContextImpl为您提供了一个关键的Collection对的幻觉/抽象。
就像我在开始时说的那样......
要记住的最重要的事情是Iterable 没有集合支持,它是在调用next()方法时动态计算的。请记住这一点。
这个主题在MapReduce框架中是通用的,所有的计算都是在流上完成的,没有任何内容完全被加载到内存中,我花了一些时间才得到这个:)因此渴望分享它。
答案 1 :(得分:1)
对reducer输入中的每个键组执行reduce()方法。 在您将多个文本用作密钥的一部分的情况下,使用文本作为密钥对密钥进行分组,因此您的输出将是
KeyGroup1,count1
KeyGroup2,count2
现在,当仅基于键的左侧部分更改分组时,还原的分组也会更改,从而提供
的输出 NewKeyGroup1, count1
NewKeyGroup2, count2
有关更深入的理解,请参阅权威指南第8章“次要排序”一节