Распределенный процесс обновления глобальной / единственной переменной в Spark - PullRequest
0 голосов
/ 04 мая 2018

У меня проблемы с попыткой обработки огромного количества данных в кластере.

код:

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, х 3 ) делает весь процесс независимым. Каждый процесс генерирует вывод (z 0 , z 1 , z 2 , z 3 ), и окончательное значение z равно среднее из этих 4 результатов.

Этот подход работает, но на точность (и время вычислений) влияет количество разделов.

Мой вопрос заключается в том, существует ли способ генерирования «глобального» z, который будет обновляться из каждого процесса (раздела).

1 Ответ

0 голосов
/ 04 мая 2018

TL; DR Нет. У Spark нет общей памяти с синхронизированным доступом, поэтому истинного глобального доступа не может быть.

Единственная форма «разделяемой» записываемой переменной в Spark - Accumulator. Он разрешает доступ только для записи с коммутативной и ассоциативной функцией.

Поскольку его реализация эквивалентна reduce / aggregate:

  • Каждый раздел имеет свою собственную копию, которая обновляется локально.
  • После выполнения задачи частичные результаты отправляются драйверу и объединяются с «глобальным» экземпляром.

это не решит вашу проблему.

...