我正在尝试在每个分区上重置longAccumulator
,但是无法重置。我正在尝试这种方式。
val list = (1 to 100).toList
val rdd = sc.parallelize(list,4)
val acc = sc.longAccumulator("1L")
rdd.mapPartitionsWithIndex{(i,iterator) =>
acc.reset()
acc.add(iterator.sum)
iterator
}
当前,此代码不会重置每个分区上的累加器。在驱动程序中,我们可以通过调用reset()
方法将累加器重置为零。我想问问是否可以为每个分区重置累加器。
我有n个分区。我想将值的总和存储在List
中的每个分区上。对于分区0,其总和应存储在列表的索引0中,依此类推。
答案 0 :(得分:1)
在大多数情况下,哪个分区(或它们的总和)中的值无关紧要并易于更改。但是,仍然可以进行计算。
您不想使用累加器对每个分区的值求和。相反,您可以模拟计算总和并将其作为新的RDD返回。
要按分区顺序获取总和列表,请返回具有总和的索引并对其进行排序。然后将其删除。
rdd.mapPartitionsWithIndex{(i,iterator) =>
Seq((i, iterator.reduce(_ + _))).toIterator
}.collect().sortBy(_._1).map(_._2)
这将为您提供一个按顺序排列总和的数组。
答案 1 :(得分:1)
根据您的最终游戏,您可能要使用自定义地图累加器。 看一下this。如下使用它:
val myAcc = new ByKeyAdditiveAccumulator[Int, Long]
sparkContext.register(myAcc)
...
rdd.foreachPartition(partition =>
acc.add((TaskContext.get.partitionId(), partition.size))
...
import scala.collection.JavaConverters._
val partitionCount = myAcc.value.asScala