2013-01-14 42 views
1

我從我的映射輸出中:的MapReduce,排序的值

Mapper: KEY, VALUE(Timestamp, someOtherAttrbibutes) 

我減速確實收到:

Reducer: KEY, Iterable<VALUE(Timestamp, someOtherAttrbibutes)> 

我想Iterable<VALUE(Timestamp, someOtherAttrbibutes)>時間戳下令屬性。有沒有可能實施它?

我想避免手動排序Reducer代碼。 http://cornercases.wordpress.com/2011/08/18/hadoop-object-reuse-pitfall-all-my-reducer-values-are-the-same/

我將不得不從「Iterable」「深度複製」所有對象,這可能會導致巨大的內存開銷。 :(((

回答

6

這是比較容易的,你需要編寫比較類的VALUE

仔細看看這裏:。http://vangjee.wordpress.com/2012/03/20/secondary-sorting-aka-sorting-values-in-hadoops-mapreduce-programming-paradigm/尤其是在溶液進行二次分揀部分

+0

我讀過這篇文章的,漂亮的同樣是在Hadoop中所描述的,defenitive指南3.我的理解,我必須移動我的T imestamp屬性鍵和鍵組合:[EXISTING_KEY_VALUE,Timestamp_attr_from_value]。如果是的話,我不喜歡這種方法。對我來說,這對我的業務並不自然,可以混淆其他開發者...... :( – Sergey

+0

+1 - 這是最好的方法,對不起! –

+0

好的,我會做的。謝謝... – Sergey

-1

你需要編寫比較類的價值類。

@Override 
protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { 
    final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    sdf.setTimeZone(TimeZone.getTimeZone("UTC")); 
    List<String> list = new ArrayList<String>(); 
    for (Text val : values) { 
     list.add(val.toString()); 

    } 
    Collections.sort(list, new Comparator<String>() { 
     public int compare(String s1, String s2) { 
      String str1[] = s1.split(","); 
      String str2[] = s2.split(","); 
      int time1 = 0; 
      int time2 = 0; 
      try { 
       time1 = (int)(sdf.parse(str1[0]).getTime()); 
       time2 = (int) (sdf.parse(str2[0]).getTime()); 

      } catch (ParseException e) { 
       e.printStackTrace(); 
      } finally { 
       return time1 - time2; 
      } 
     } 
    }); 
    for(int i = 0; i < list.size(); ++i) 
    context.write(key, new Text(list.get(i))); 
} 
+0

這是一個很好的答案,但一些解釋可能不錯。 – Tgsmith61591