ParallelCollectionRDD.reducebykey(_-_)没有给出正确的结果

时间:2019-01-07 01:24:16

标签: scala apache-spark

我正在尝试获取RDD上的reduceByKey函数以下的值,但是未给出正确的结果。

scala> val test =sc.parallelize(( (1 to 5).map(x=>("key",x)))).reduceByKey(_-_).collect
res62: Array[(String, Int)] = Array((key,-3))

然后我尝试进行以下计算

scala> List (1,2,3,4,5).reduce(_-_)
res65: Int = -13

之所以会这样,是因为RDD操作中没有顺序的保证,因此reduce函数以任何顺序应用,而在确保List顺序的情况下,reduce函数的行为正确。

1 个答案:

答案 0 :(得分:3)

这不是错误,而是预期的行为。如果您打开reduceByKey的文档,则可能会看到(重点是我的):

  

使用关联和可交换归约函数合并每个键的值。

这两个属性对于并行化是必不可少的:

减法既不是关联的也不是可交换的。因此reduceByKey的结果是不确定的。

实际上,甚至Scala标准库GenTraversable.reduce都说(再次强调是我的)

  

使用指定的关联二元运算符减少此集合或迭代器的元素。

     


对元素进行操作的顺序未指定,可能不确定。

因此,声明“ 而在保证列表顺序的情况下,reduce函数的行为正确”的主张也是错误的。 List上的顺序是一个实现细节,理论上可以随时更改(尽管实际上出于性能考虑,这不太可能发生)。

只要您想知道如何实现-3,这就是一种可能的解释:

(-1 - -2 - -3) - (-4 - -5)