java hadoop作业在reducer outputcollector中的操作1/double(一个除法一个双精度)中的奇怪行为

bogh5gae  于 2021-06-04  发布在  Hadoop
关注(0)|答案(1)|浏览(241)

在用java编写的hadoopmapreduce作业中,我发现,在reduce阶段,划分是不稳定的。在特定的1/x和x double中:

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

值是迭代器。
当总和不同于零时,有时写1/总和,有时写总和。我快疯了。谢谢
[已解决]我遇到另一个问题,mapper和reducer接口(键值)不同(文本,不可写)第一个(文本,可双写)第二个。我在“main”中配置了这个东西。错误还在继续,因为我放错了这一行:

conf.setCombinerClass(Reduce.class);

在mapper和reducer中需要相同的接口(k,v),这不是我的情况;一切正常。多亏了阿农·罗特姆·加洛兹,我才没有名声支持他

zlwx9yxi

zlwx9yxi1#

您的问题是,浮点值的加法在计算和时是不可交换的(其原因是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);
        }
    }

}

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

相关问题