鉴于以下内容:
val rdd = List(1,2,3)
我认为rdd.reduce((x,y) => (x - y))
会返回-4
(即(1-2)-3=-4
),但会返回2
。
为什么?
答案 0 :(得分:7)
从RDD源代码(和docs):
/**
* Reduces the elements of this RDD using the specified commutative and
* associative binary operator.
*/
def reduce(f: (T, T) => T): T
reduce
是一个单调缩减,因此它假设函数是可交换和关联,这意味着不能保证将它应用于元素的顺序。
显然,你的函数(x,y)=>(x-y)
不是可交换的,也不是关联的。
在您的情况下,reduce可能是以这种方式应用的:
3 - (2 - 1) = 2
或
1 - (2 - 3) = 2
答案 1 :(得分:2)
您可以使用 v1 - (v2 + ... + vN)轻松替换减法 v1 - v2 - ... - vN ,因此您的代码可能看起来像
val v1 = 1
val values = Seq(2, 3)
val sum = sc.paralellize(values).reduce(_ + _)
val result = v1 - sum
答案 2 :(得分:1)
正如@TzachZohar所述,函数必须满足两个属性,以便并行计算是合理的;通过收集 rdd,reduce
放松了函数中所需的属性,因此它产生了顺序(非并行)计算的结果,即
val rdd = sc.parallelize(1 to 3)
rdd.collect.reduce((x,y) => (x-y))
Int = -4