hadoop NaturalKeyGroupingComparator - Reducer中发生了什么?

时间:2014-05-13 13:31:57

标签: java hadoop mapreduce

我目前正在开发一个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运行的中间改变键?

2 个答案:

答案 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;
    }

这是ReduceContextImpl

的摘录

每次调用该方法,你调用next(),它基本上检查键是否在底层流中发生变化,如果不是它只是传递给你下一个值(记住键是有序的),否则它安排调用reducer方法再次使用新密钥并可迭代。

底层流始终是一个键值对,ReducerContextImpl为您提供了一个关键的Collection对的幻觉/抽象。

就像我在开始时说的那样......

要记住的最重要的事情是Iterable 没有集合支持,它是在调用next()方法时动态计算的。请记住这一点。

这个主题在MapReduce框架中是通用的,所有的计算都是在流上完成的,没有任何内容完全被加载到内存中,我花了一些时间才得到这个:)因此渴望分享它。

答案 1 :(得分:1)

对reducer输入中的每个键组执行reduce()方法。 在您将多个文本用作密钥的一部分的情况下,使用文本作为密钥对密钥进行分组,因此您的输出将是

KeyGroup1,count1

KeyGroup2,count2

现在,当仅基于键的左侧部分更改分组时,还原的分组也会更改,从而提供

的输出
 NewKeyGroup1, count1
 NewKeyGroup2, count2

有关更深入的理解,请参阅权威指南第8章“次要排序”一节