2011-05-23 47 views
3

的Hadoop版本的值的迭代過程中修改我的重點對象:0.20.2(亞馬遜EMR)Hadoop的似乎是在給定的減少通話

問題:我有,我在地圖相編寫自定義的按鍵,我在下面添加。在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; 
    } 
} 

這有什麼不對的實施重點的?以下是我正在面對的混合鍵減少電話的代碼:

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 
} 

任何幫助在這將不勝感激。

+1

這可能聽起來很奇怪,但我認爲如果你刪除了compareTo方法的hashcode部分並返回-1,那麼它應該可以正常工作。 – 2011-05-23 14:50:06

+0

謝謝托馬斯。這聽起來很奇怪,但我非常絕望,無論如何我都嘗試過。首先,上面的代碼起作用。我可恥地承認,我粘貼的代碼完全不是我正在運行的代碼。我只是在做'return this.subKeys.hashCode() - o.subKeys.hashCode()',我知道這是錯誤的,但我沒有修復實際的代碼,而是試着比較兩個似乎在碰撞的鍵的hashCode。我在測試中犯了一個錯誤,並假設其他東西是錯誤的,並在此處修復了代碼。 – Bhargava 2011-05-23 17:51:54

回答

5

這是預期的行爲(至少使用新的API)。

當調用值爲Iterable的基礎迭代器的next方法時,將從排序後的映射器/組合器輸出中讀取下一個鍵/值對,並檢查該鍵是否仍然是前一組的相同組的一部分鍵。

因爲hadoop重新使用傳遞給reduce方法的對象(只調用同一對象的readFields方法),Key參數'k'的基礎內容將隨着Iterable的每次迭代而改變。