【问题标题】:Get Top N items from mapper output - Mapreduce从映射器输出中获取前 N 个项目 - Mapreduce
【发布时间】:2015-09-25 22:17:30
【问题描述】:

我的 Mapper 任务返回以下输出:

2   c
2   g
3   a
3   b
6   r

我已经编写了生成正确输出的 reducer 代码和 keycomarator,但是我如何获得 Mapper 输出的前 3 个(按计数前 N 个):

public static class WLReducer2 extends
        Reducer<IntWritable, Text, Text, IntWritable> {

    @Override
    protected void reduce(IntWritable key, Iterable<Text> values,
            Context context) throws IOException, InterruptedException {

        for (Text x : values) {
            context.write(new Text(x), key);
        }

    };

}

public static class KeyComparator extends WritableComparator {
    protected KeyComparator() {
        super(IntWritable.class, true);
    }

    @Override
    public int compare(WritableComparable w1, WritableComparable w2) {
        // TODO Auto-generated method stub

        // Logger.error("--------------------------> writing Keycompare data = ----------->");
        IntWritable ip1 = (IntWritable) w1;
        IntWritable ip2 = (IntWritable) w2;
        int cmp = -1 * ip1.compareTo(ip2);

        return cmp;
    }
}

这是reducer的输出:

r   6
b   3
a   3
g   2
c   2

reducer 的预期输出是计数前 3 位,即:

r   6
b   3
a   3

【问题讨论】:

    标签: hadoop mapreduce bigdata


    【解决方案1】:

    限制减速器的输出。像这样的。

    public static class WLReducer2 extends
            Reducer<IntWritable, Text, Text, IntWritable> {
        int count=0;
        @Override
        protected void reduce(IntWritable key, Iterable<Text> values,
                Context context) throws IOException, InterruptedException {
    
            for (Text x : values) {
                if (count > 3)
                context.write(new Text(x), key);
                count++;
            }
    
        };
    }
    

    将减速器的数量设置为 1。job.setNumReduceTasks(1)

    【讨论】:

    • 谢谢,该解决方案确实对我有用。将减速器数量设置为 1 不会造成性能问题?
    • 我们不会在输出中写太多,因为我们需要计算前 N 个元素,我们必须将数据带到单个 reducer 来计算它。您可以使用组合器(取决于数据集)来减少一些性能瓶颈。
    • 只要考虑count语句应该是if(count
    【解决方案2】:

    如果您的 Top-N 元素可以存储在内存中,您可以使用 TreeMap 来存储 Top-N 元素,并且如果您的流程可以仅使用一个 reducer 进行聚合。

    1. 在 reducer 的 setup() 方法中实例化一个实例变量 TreeMap。
    2. reducer() 方法中,您应该聚合键组的所有值,然后将结果与树中的第一个(最低)键 map.firstKey() 进行比较。如果您的当前值大于树中的最小值,则将当前值插入树图中map.put(value, Item),然后从树中删除最小值map.remove(value)
    3. 在 reducer 的 cleanup() 方法中,按要求的顺序将 TreeMap 的所有元素写入输出。

    注意:用于比较记录的必须是 TreeMap 中的。而你的TreeMap的value应该是描述、标签、字母等;与号码相关。

    【讨论】:

      猜你喜欢
      • 2016-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      • 2018-04-04
      • 1970-01-01
      • 2018-08-30
      • 1970-01-01
      相关资源
      最近更新 更多