MapReduce:为什么我不能这样做二级排序(Hadoop)?

时间:2014-01-24 20:41:54

标签: hadoop mapreduce

我使用正确的方法实现了Secondary Sort:复合键,复合键比较器类,自然键分组比较器类和自然键分区器类。

然而,在我得知这是必要的之前,我做了以下几点:

class CompositeKey extends WritableComparable<CompositeKey> {
    String name; // Natural Key
    Date time;   // Secondary Sort on this value

    // Constructor

    public void readFields(DataInput in) { ... }
    public void readFields(DataInput out) { ... }
    public int compareTo(CompositeKey compositeKey) { 
        int result = getName().compareTo(compositeKey.getName());
        if (result == 0) {
            result = getTime().compareTo(compositeKey.getTime());
        }
        return result
    }

    public boolean equals(Object compositeKey) {
        // Similar code to compareTo()
    }


} 

我认为Mapper会发出由CompositeKey组合在一起的值,其相等性将由compareTo或equals方法确定。

为什么这种方法不起作用?

鉴于大多数情况下Mapper发出的Key类是.. hadoop.io.Text类,MapReduce如何计算成员变量bytes是需要比较的为了分组价值?为什么不能像上面的班级那样使用更高级的逻辑进行二次排序?

编辑我刚才注意到了..hadoop.io.Text:

的源代码
350      /** A WritableComparator optimized for Text keys. */
351      public static class Comparator extends WritableComparator {
352        public Comparator() {
353          super(Text.class);
354        }
355    
356        @Override
357        public int compare(byte[] b1, int s1, int l1,
358                           byte[] b2, int s2, int l2) {
359          int n1 = WritableUtils.decodeVIntSize(b1[s1]);
360          int n2 = WritableUtils.decodeVIntSize(b2[s2]);
361          return compareBytes(b1, s1+n1, l1-n1, b2, s2+n2, l2-n2);
362        }
363      }
364    
365      static {
366        // register this comparator
367        WritableComparator.define(Text.class, new Comparator());
368      }

我假设如果我把它放入,它仍然不起作用(鉴于每个人都建议做上面列出的方法进行二次排序)。为什么不呢?

2 个答案:

答案 0 :(得分:0)

如果希望按主键对值进行排序并按主键分组,则通常会使用辅助排序。只使用复合键只允许您按主键和辅助键分组;一旦到达相应的Reducer,它就无法以任何排序顺序获取值。

具体来说:“Name”是主键,“Time”是辅助键,

使用二级排序:每个reducer获取与一个“Name”对应的所有值,并按排序顺序获取“Time”的每个数据点,例如Name:Bob,Time:1,2,3,...

仅使用复合键:每个reducer获取与每个“Name”,“Time”对相对应的所有值。无法保证相同的reducer将所有名称,时间对对应于同一名称,因此无法保证Bob的值按时间顺序处理。

答案 1 :(得分:0)

您可以尝试将name的类型更改为hadoop Text。这帮助了我。