计算hadoop中的'n'最大值

时间:2014-06-24 04:50:06

标签: java hadoop mapreduce max

我有一个场景。以前job1

的输出

在下一个工作中,我需要找到具有最大值的i密钥。例如i = 3,具有最大值的3个密钥。i将是自定义参数)

如何解决这个问题。

我们应该在job2映射器中计算max因为会有唯一键,因为输出来自之前的reducer 要么 在第二个作业reducer中找到max。但是又如何查找i个键?

更新

我试过这种方式 而不是在reducer中将值作为值发出。我将值作为键发出,因此我可以按升序获取值。 我写了下一个MR job.where mapper只是发出键/值。

Reducer找到key的最大值 但是我再次陷入困境,因为我们试图获取id,所以无法完成,因为id只是唯一的,值不是唯一的。

如何解决这个问题。

任何人都可以为此提出解决方案。

提前致谢。

1 个答案:

答案 0 :(得分:1)

您可以使用i找到热门PriorityQueue密钥。简单的代码来说明这个想法:

public static class TopNMapper extends Mapper<IntWritable, DoubleWritable, IntWritable, DoubleWritable> {
    private static class MyPair implements Comparable<MyPair> {
        public final int key;
        public final double value;

        MyPair(int key, double value) {
            this.key = key;
            this.value = value;
        }

        @Override
        public int compareTo(MyPair o) {
            return -Double.compare(value, o.value); // i'm not sure about '-'
        }
    }

    private final PriorityQueue<MyPair> topN = new PriorityQueue<MyPair>();

    @Override
    protected void map(IntWritable key, DoubleWritable value, Context context) throws IOException, InterruptedException {
        if (Double.isNaN(value.get())) {
            return; // not a number
        }
        topN.add(new MyPair(key.get(), value.get()));
        if (topN.size() <= 50) { // simple optimization
            return;
        }
        while (topN.size() > 3) { // retain only top 3 elements in queue
            topN.poll();
        }
    }

    @Override
    protected void cleanup(Context context) throws IOException, InterruptedException {
        while (topN.size() > 3) {
            topN.poll(); // retain only top 3 elements in queue
        }
        for (MyPair myPair : topN) { // write top 3 elements
            context.write(new IntWritable(myPair.key), new DoubleWritable(myPair.value));
        }
    }
}

如果你运行这个映射器(一个用于所有输入),你应该得到3个具有最大值的键。