-1

在用 Java 编写的 Hadoop MapReduce 作业中,我发现在 REDUCE 阶段,除法不稳定。在特定的 1 / X 和 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));
 }

values 是一个迭代器。

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

[已解决] 我还有一个问题,MAPPER和REDUCER的接口(key-value)不同。(Text, InteWritable) 第一个 (Text, DoubleWritable) 第二个。我在“主要”中配置了这些东西。错误仍在继续,因为我输入此行是错误的:

conf.setCombinerClass(Reduce.class);

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

4

1 回答 1

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);
        }
    }

}

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

于 2013-05-28T18:22:28.263 回答