在行动中执行火花累积器的困惑

时间:2017-03-29 07:09:52

标签: apache-spark pyspark

从官方文档我们可以看到:

  

对于仅在操作内执行的累加器更新,Spark   保证每个任务对累加器的更新只会是   应用一次,即重新启动的任务不会更新该值。在   转换时,用户应该知道每个任务的更新可能   如果重新执行任务或工作阶段,则应用多次。

我认为这意味着累加器只应在动作内执行,例如rdd.foreachPartition()

通过pyspark中的rdd.foreachPartition API代码,我发现rdd.foreachPartition(accum_func)等于:

rdd.mapPartitions(accum_func).mapPartitions(lambda i: [sum(1 for _ in i)]).mapPartitions(lambda x: [sum(x)]).mapPartitions(some_add_func).collect()

似乎 accum_func 可以在转换(rdd.mapPartition)中运行?

非常感谢任何解释

1 个答案:

答案 0 :(得分:0)

如果运行map()操作分区的节点崩溃, Spark会在另一个节点上重新运行它,即使该节点没有崩溃,也只是简单 比其他节点慢得多,Spark可以抢先推出“推测”副本 另一个节点上的任务,如果完成则取结果。

即使没有节点发生故障,Spark也可能不得不重新运行任务来重建一个内存不足的缓存值。因此,最终结果是相同的函数可能会在同一数据上运行多次,具体取决于群集。

动作中使用的累加器,Spark仅将每个任务的更新应用于每个累加器一次。因此,如果我们想要一个可靠的绝对值计数器,无论是失败还是多次评估,我们都必须把它放在像foreach()这样的动作中。