Изменение моего комментария на ответ по запросу. Оригинальный комментарий
Вы изменяете arrSum в JVM исполнителя и печатаете его значения в JVM dirver. Вы можете сопоставить итераторы с одноэлементными итераторами и использовать команду collect для перемещения значений в драйвер. Кроме того, не используйте iterator.map для побочных эффектов, для этого предназначен iterator.foreach.
А вот пример кода, как это сделать. Сначала создайте СДР с двумя разделами, 0 -> 1,2,3
и 1 -> 4,5
. Естественно, вам не понадобится это в реальном коде, но, поскольку поведение sc.parallelize
меняется в зависимости от среды, это всегда будет создавать единые СДР для воспроизведения:
object DemoPartitioner extends Partitioner {
override def numPartitions: Int = 2
override def getPartition(key: Any): Int = key match {
case num: Int => num
}
}
val rdd = sc
.parallelize(Seq((0, 1), (0, 2), (0, 3), (1, 4), (1, 5)))
.partitionBy(DemoPartitioner)
.map(_._2)
А потом действительный трюк:
val sumsByPartition = rdd.mapPartitionsWithIndex {
case (partitionNum, it) => Iterator.single(partitionNum -> it.sum)
}.collect().toMap
println(sumsByPartition)
Выходы:
Map(0 -> 6, 1 -> 9)