2013-01-14 41 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