java hadoop在reducer outputcollector中的操作1 / double(ONE DIVISION a Double)中的奇怪行为

时间:2013-05-28 17:17:36

标签: java hadoop mapreduce division

在用Java编写的Hadoop MapReduce作业中 在REDUCE的阶段,我发现分裂的不稳定性。在具有X double的特定1 / X中:

double sum = 0;
 while (values.hasNext())
 {
    sum += values.next().get();
 }
 if (sum != 0) {
    output.collect(key, new DoubleWritable(1/sum));
 } else {
   output.collect(key, new DoubleWritable(1));
 }

值是迭代器。

当总和与ZERO不同时,有时会写1 / sum和SOMETIMES WRITE sum。 它让我发疯。 非常感谢

[解决] 我有另一个问题,MAPPER和REDUCER接口(键值)不同。 (Text,InteWritable)第一个(Text,DoubleWritable)第二个。 我在“主要”中配置了这些东西。错误仍在继续,因为我把这一行放错了:

conf.setCombinerClass(Reduce.class);

在mapper和reducer中需要相同的接口(k,v),这不是我的情况; 删除一切正常。 感谢Arnon Rotem-Gal-Oz,我没有声誉支持他

1 个答案:

答案 0 :(得分:1)

你的问题是,在计算总和时,浮点值的加法是不可交换的(其原因是double的有限精度)。用简单的话来说:总和受到元素添加顺序的影响。

这段代码很好地证明了这一点:

public class DoubleSumDemo {

    public static void main(String[] argv) {
        final ArrayList<Double> list = new ArrayList<Double>();
        // fill list with random values
        for (int i=0; i<1000000; ++i)
            list.add(Math.random());
        // sum the list, print the sum and then reorder the list elements
        while (true) {
            double sum = 0D;
            for (double element : list) 
                sum += element;
            System.out.println("sum is: " + sum);
            Collections.shuffle(list);
        }
    }

}

虽然列表只填充一次,但它会在每个循环上打印不同的总和。