【问题标题】:MapReduce sort by value in descending orderMapReduce 按值降序排序
【发布时间】:2020-07-28 02:08:52
【问题描述】:

我正在尝试用伪代码编写一个 MapReduce 任务,该任务返回按降序排序的项目。例如:对于 wordcount 任务,而不是获取:

apple 1
banana 3
mango 2

我希望输出是:

banana 3
mango 2
apple 1

关于如何做的任何想法?我知道如何按升序(替换映射器作业中的键和值)而不是降序。

【问题讨论】:

  • 只要搜索“mapreduce 二级排序”,你会发现很多例子。
  • @BinaryNerd 如果我没记错的话,这不是二级排序。这只是按值排序,比二级排序更容易。
  • 按值排序是hadoop mapreduce中的二级排序,一级排序在key上。
  • @BinaryNerd 在二级排序中,按相同键的值进行排序。就我而言,我不在乎键是什么。

标签: sorting hadoop mapreduce pseudocode


【解决方案1】:

这里你可以借助下面的reducer代码来实现降序排序。

假设您已经编写了映射器和驱动程序代码,其中映射器将生成输出为 (Banana,1) 等

在 reducer 中,我们将对特定键的所有值求和,并将最终结果放入 map 中,然后根据值对 map 进行排序,并将最终结果写入 reduce 的清理函数中。

请参阅下面的代码以了解更多信息:

public class Word_Reducer extends Reducer<Text, IntWritable, Text, IntWritable> {
    // Change access modifier as per your need 
    public Map<String , Integer > map = new LinkedHashMap<String , Integer>();
    public void reduce(Text key , Iterable<IntWritable> values ,Context context)
    { 
    // write logic for your reducer 
    // Enter reduced values in map for each key
    for (IntWritable value : values ){
         // calculate "count" associated with each word 
    }
    map.put(key.toString() , count); 
}

public void cleanup(Context context){ 
    //Cleanup is called once at the end to finish off anything for reducer
    //Here we will write our final output
    Map<String , Integer>  sortedMap = new HashMap<String , Integer>();    
    sortedMap = sortMap(map);

    for (Map.Entry<String,Integer> entry = sortedMap.entrySet()){
        context.write(new Text(entry.getKey()),new IntWritable(entry.getValue()));
    }
}

public Map<String , Integer > sortMap (Map<String,Integer> unsortMap){
    Map<String ,Integer> hashmap = new LinkedHashMap<String,Integer>();
    int count=0;
    List<Map.Entry<String,Integer>> list = new 
    LinkedList<Map.Entry<String,Integer>>(unsortMap.entrySet());
    //Sorting the list we created from unsorted Map
    Collections.sort(list , new Comparator<Map.Entry<String,Integer>>(){
        public int compare (Map.Entry<String , Integer> o1 , Map.Entry<String , Integer> o2 ){
            //sorting in descending order
            return o2.getValue().compareTo(o1.getValue());
        }
    });

    for(Map.Entry<String, Integer> entry : list){
        // only writing top 3 in the sorted map 
        if(count>2)
            break;
        hashmap.put(entry.getKey(),entry.getValue());
    }
    return hashmap ; 
}

【讨论】:

  • 感谢您的回答!我从您的回答中了解到如何对同一键的值进行排序。我不认为所有字符串和整数的 Map 都会通过这整个过程保存。另外,我怎么知道什么时候调用清理函数?
  • reduce 任务结束时自动调用一次清理函数。
  • 好的,很好。我提到的第一件事呢?我不认为键和值的映射在整个过程中被保存和更新,我认为唯一的变量是计数器。我错了吗?
  • 我没有理解你所说的对同一个键的值进行排序的意思,并且在计算过程中所有的地图都将在内存中。
  • 我想要的是按值排序,无论键是什么。您设置了一个linkedhashmap: public Map map = new LinkedHashMap();并说它会收集所有键的所有值,对吗?所以,我认为不会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 1970-01-01
相关资源
最近更新 更多