我遇到了 Spark 作业的问题,大约每 2 次就会失败一次,并显示以下错误消息:
org.apache.spark.SparkException:作业由于阶段失败而中止:A 输出不确定的随机映射阶段失败并重试。 但是,Spark 无法回滚 ResultStage XYZ 来重新处理 输入数据,并且必须使这项工作失败。请消除 通过在重新分区之前检查 RDD 来确定不确定性并尝试 再次。
这种情况发生在 Databricks 13.3 LTS(基于 Apache Spark 3.4.1)上。我开始逐步消除对
repartition(...)
的调用,直到没有剩余,但我仍然收到上述错误。我的下一个假设是,这是由于“自适应查询执行”(AQE)可能会动态更改分区。但关闭 AQE 也没有帮助。
如果没有显式调用 repartition
或 AQE,还有什么可能导致上述错误,以及可以采取哪些措施来防止它?
checkpoint(eager=False)
。通过用急切的检查点替换非急切的检查点,问题似乎已经消失了。
请注意,根据https://github.com/apache/spark/blob/6d4d76463144c7c493cfd1f3bf5950c803d45f49/sql/core/src/main/scala/org/apache/spark/sql/Dataset.scala#L705当 checkpoint 与 eager = false 一起使用时,由于底层操作和重试的不确定性,第一个操作后检查点的最终数据可能与作业期间使用的数据不同。如果使用checkpoint来实现保存数据的确定性快照,则应使用 eager = true 。否则,只有在检查点最终确定后、第一次执行后才是确定的。