SparkListener 如何检测未执行 job 时的应用失败?
数据阿明
结论
仅凭 SparkListener 收到的事件,无法可靠判断 Spark 应用是否因 driver 端异常而失败。onApplicationEnd 会提供应用结束事件,但不包含应用级的成功或失败状态。如果异常发生在 job 之外,listener 也可能只收到此前成功完成的 job 事件。因此,不修改 job 代码时,不能把这类事件流视为完整的应用失败信号。
为什么事件序列不足以判断
题述场景中,应用先成功完成一个 action,随后在 driver 逻辑中出错。listener 可能只收到一次成功的 onJobEnd,接着收到 onApplicationEnd。仅凭这组事件,无法区分应用是否只定义并成功执行了一个 action,还是原本还有后续逻辑、却在 driver 上失败。
onJobEnd 只说明对应 job 的状态,不能代表整个应用的状态。题目还指出,在所述 Spark 4 场景中,exit status 仍可能是 0,因此也不能单靠这个值判断应用是否成功。
不修改 job 代码时的兜底办法
应用级状态需要通过 SparkListener 之外的信号采集:
- 在提交端记录进程退出码。 如果使用 client 模式提交,可以让外部提交脚本或调度器记录
spark-submit进程的退出结果,再将该结果与 listener 产生的 OpenLineage 事件关联,作为补充状态。 - 查询集群管理器的应用状态和诊断信息。 在支持的部署环境中,可以从集群管理器或调度平台读取 driver 是否失败及相关诊断信息。可用字段和状态因部署模式及管理器而异,需要按实际环境确认。
- 在启动入口外围捕获异常并上报。 如果可以调整启动脚本或外部包装入口,就能在外围记录异常并设置非零退出码。这不需要改动业务 action,但需要能够控制应用的启动方式。
这些办法采集的都是 listener 事件之外的信号,SparkListener 本身无法补上应用级失败状态。如果系统只能使用 listener 事件,应将无法判定的应用标记为“状态未知”,不要自动把 onApplicationEnd 解释为成功。
备注:内容仅供参考。
