Apache Spark中的reduce()和fold()的区别

6

关于技术实现,reducefold有何不同?

据我了解,它们的签名不同,fold接受额外的参数(即初始值),该值会添加到每个分区的输出中。

  • 有人能讲解一下这两种操作的用例吗?
  • 如果考虑使用0作为fold的参数,在哪种情况下哪种操作会表现更好?

先谢谢啦。


6
我认为这不是一个与Spark相关的问题,更好的做法是阅读其他资源或问题。https://dev59.com/hV8e5IYBdhLWcg3w_-dM - anquegi
@TheArchetypalPaul fold(不是foldLeft / foldRight)也可以(而且也被)并行化。 - zero323
@zero323 嗯,说得好,我以为是指foldLeft。投票重新开放。 - The Archetypal Paul
1
从源代码来看,它们基本上会在相同的时间内运行。fold 对每个分区的迭代器调用 fold,然后合并结果,reduce 对每个分区的迭代器调用 reduceLeft,然后合并结果。不同之处在于,fold 不需要担心空分区或集合,因为它将使用零值。性能差异可能甚至无法测量。 - The Archetypal Paul
1
@zero323,没问题,这是一个很好的回答,我们都不需要声望值 :) - The Archetypal Paul
显示剩余3条评论
1个回答

10

就性能而言,RDD.fold 操作使用 foldLeft 在分区的 Iterators 上执行 fold,而 RDD.reduce 则是在分区的 Iterators 上使用 reduceLeft

这两种方法都保留可变累加器,并使用类似于 foldLeft 的简单循环顺序处理分区。

foreach (x => result = op(result, x))

并使用 reduceLeft 来实现:

for (x <- self) {
  if (first) {
    ...
  }
  else acc = op(acc, x)
}

在Spark中,这些方法的实际区别仅与它们在空集合上的行为和使用可变缓冲区的能力有关(可以说这与性能相关)。在Why is the fold action necessary in Spark?中可以找到一些讨论。

此外,在整个处理模型方面没有区别:

  • 每个分区使用单个线程顺序处理。
  • 使用多个执行器/执行器线程并行处理分区。
  • 最终合并在驱动程序上使用单个线程顺序执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接