代码之家  ›  专栏  ›  技术社区  ›  jrdi

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

  •  0
  • jrdi  · 技术社区  · 6 年前

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

    代码:

    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个块(x 0 ,x 1. ,x 2. ,x 3. )使所有流程独立。每个进程生成一个输出(z 0 z 1. z 2. z 3. ),z的最终值是这4个结果的平均值。

    这种方法可行,但精度(和计算时间)受分区数量的影响。

    我的问题 是否有一种生成“全局”z的方法,该z将从每个进程(分区)更新。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Alper t. Turker    6 年前

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

    Spark中“共享”可写变量的唯一形式是 Accumulator . 它允许使用交换和关联功能进行只写访问。

    因为它的实现相当于 reduce / aggregate :

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

    这不能解决你的问题。