我正在尝试获取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函数的行为正确。
答案 0 :(得分:3)
这不是错误,而是预期的行为。如果您打开reduceByKey的文档,则可能会看到(重点是我的):
使用关联和可交换归约函数合并每个键的值。
这两个属性对于并行化是必不可少的:
Associativity表示(a ∗ b) ∗ c = a ∗ (b ∗ c)
(其中∗
是运算符)
Commutativity的意思是a ∗ b = b ∗ a
减法既不是关联的也不是可交换的。因此reduceByKey
的结果是不确定的。
实际上,甚至Scala标准库GenTraversable.reduce都说(再次强调是我的)
使用指定的关联二元运算符减少此集合或迭代器的元素。
对元素进行操作的顺序未指定,可能不确定。
因此,声明“ 而在保证列表顺序的情况下,reduce函数的行为正确”的主张也是错误的。 List
上的顺序是一个实现细节,理论上可以随时更改(尽管实际上出于性能考虑,这不太可能发生)。
只要您想知道如何实现-3,这就是一种可能的解释:
(-1 - -2 - -3) - (-4 - -5)