分布式进程更新 Spark 中的全局/单个变量



我在尝试处理集群上的大量数据时遇到了麻烦。

代码:

val (sumZ, batchSize) = data.rdd.repartition(4)
.treeAggregate(0L, 0L))(
seqOp = (c, v) => {
// c: (z, count), v
val step = this.update(c, v)
(step._1, c._2 + 1)
},
combOp = (c1, c2) => {
// c: (z, count)
(c1._1 + c2._1, c1._2 + c2._2)
})
val finalZ = sumZ / 4

正如您在代码中看到的,我目前的方法是处理将这些数据分区为 4 个块(x0、x1、x2、x3(,使所有进程独立。每个过程生成一个输出(z0, z1, z2, z3(,z 的最终值是这 4 个结果的平均值。

这种方法有效,但精度(和计算时间(受分区数的影响。

我的问题是是否有一种方法可以生成将从每个进程(分区(更新的"全局"z。

TL;DR没有。Spark 没有具有同步访问的共享内存,因此不存在真正的全局访问。

Spark中"共享"可写变量的唯一形式是Accumulator。它允许具有交换和关联函数的只写访问。

由于它的实现等效于reduce/aggregate

  • 每个分区都有自己的副本,该副本在本地更新。
  • 任务完成后,部分结果将发送到驱动程序并与"全局"实例组合。

它不会解决您的问题。

最新更新