Hadoop似乎在迭代期间修改了我的密钥对象,而不是给定reduce调用的值

Bha*_*ava 5 reduce hadoop elastic-map-reduce

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;
  }
}
Run Code Online (Sandbox Code Playgroud)

这个密钥的实现有什么问题吗?以下是我在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
}
Run Code Online (Sandbox Code Playgroud)

任何帮助都将非常感谢.

Chr*_*ite 5

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

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

因为hadoop重新使用传递给reduce方法的对象(只调用同一对象的readFields方法),所以Key参数'k'的基础内容将随valuesIterable的每次迭代而改变.