5

Hadoop 版本:0.20.2(在 Amazon EMR 上)

问题:我有一个在映射阶段编写的自定义键,我在下面添加。在 reduce 调用期间,我对给定键的值进行了一些简单的聚合。我面临的问题是,在 reduce 调用中的值迭代过程中,我的键发生了变化,并且我得到了那个新键的值。

我的密钥类型:

 class MyKey implements WritableComparable<MyKey>, Serializable {
    private MyEnum type; //MyEnum is a simple enumeration.
    private TreeMap<String, String> subKeys;

    MyKey() {} //for hadoop
    public MyKey(MyEnum t, Map<String, String> sK) { type = t; subKeys = new TreeMap(sk); }

    public void readFields(DataInput in) throws IOException {
      Text typeT = new Text();
      typeT.readFields(in);
      this.type = MyEnum.valueOf(typeT.toString());

      subKeys.clear();
      int i = WritableUtils.readVInt(in);
      while ( 0 != i-- ) {
        Text keyText = new Text();
        keyText.readFields(in);

        Text valueText = new Text();
        valueText.readFields(in);

        subKeys.put(keyText.toString(), valueText.toString());
    }
  }

  public void write(DataOutput out) throws IOException {
    new Text(type.name()).write(out);

    WritableUtils.writeVInt(out, subKeys.size());
    for (Entry<String, String> each: subKeys.entrySet()) {
        new Text(each.getKey()).write(out);
        new Text(each.getValue()).write(out);
    }
  }

  public int compareTo(MyKey o) {
    if (o == null) {
        return 1;
    }

    int typeComparison = this.type.compareTo(o.type); 
    if (typeComparison == 0) {
        if (this.subKeys.equals(o.subKeys)) {
            return 0;
        }
        int x = this.subKeys.hashCode() - o.subKeys.hashCode();
        return (x != 0 ? x : -1);
    }
    return typeComparison;
  }
}

这个key的实现有什么问题吗?以下是我在reduce调用中面临混合键的代码:

reduce(MyKey k, Iterable<MyValue> values, Context context) {
   Iterator<MyValue> iterator = values.iterator();
   int sum = 0;
   while(iterator.hasNext()) {
        MyValue value = iterator.next();
        //when i come here in the 2nd iteration, if i print k, it is different from what it was in iteration 1.
        sum += value.getResult();
   }
   //write sum to context
}

对此的任何帮助将不胜感激。

4

1 回答 1

5

这是预期的行为(至少使用新 API)。

next调用值 Iterable 的底层迭代器的方法时,从排序的映射器/组合器输出中读取下一个键/值对,并检查该键是否仍与前一个键属于同一组。

因为 hadoop 重用了传递给 reduce 方法的对象(只是调用同一个对象的 readFields 方法),所以 Key 参数 'k' 的底层内容会随着valuesIterable 的每次迭代而改变。

于 2012-05-17T02:03:57.243 回答