批处理任务失败后怎么办:三种恢复策略的适用边界
批处理系统跑几百个任务,零失败是幻想,真问题是失败之后怎么恢复。上周聊过断点续跑的状态机设计,这篇接下去讲恢复策略——三种常见做法,适用边界完全不同,选错就是把小故障拖成大事故。
策略一:整批重跑(简单粗暴型)
失败后从头再来。适用边界极窄:任务耗时短 + 幂等性完美 + 成本可忽略。三者缺一就会出事。实际见得最多的翻车:任务里夹着「发通知」类副作用,重跑等于给用户发两遍消息。整批重跑前先问一句:这个批处理真的全链路幂等吗?大多数系统经不起这一问。
策略二:断点续跑(工程正解型)
状态机记录每个任务的 pending/running/done/failed,重启后跳过 done、重试 failed、继续 pending。这是绝大多数场景的正解,但有三个容易漏的细节:
- running 态的孤儿任务:进程崩的时候正在跑的任务停在 running,重启后没人认领。需要「超时回收」机制——running 超过阈值的自动降级回 pending
- 部分完成的子产物:任务做了 70% 崩了,产物写了一半。续跑前要能识别并清理半成品(临时目录约定、产物原子性写入)
- 外部状态对账:任务调用过外部系统(发了请求、写了下游),续跑时下游可能已经有半份数据。要么带幂等键续跑,要么先对账再续
策略三:降级跳过 + 人工兜底(务实止损型)
失败的标记为 skipped,带着失败清单继续跑完,最后人工处理残局。适合批处理有时效性的场景:凌晨的数据报表,8 点必须出,与其卡在重试不如先跳过坏数据出个 97% 版本,附一张「缺失清单」。这个策略的关键是「缺数据不静默」——报告里必须显著标注覆盖率和缺失明细,否则下游会把残缺当完整。
选型速查
| 场景 | 推荐 |
|---|---|
| 秒级小任务、全幂等 | 整批重跑也行 |
| 长任务、有状态 | 断点续跑 + 超时回收 |
| 有硬截止时间 | 降级跳过 + 显式缺失清单 |
| 混合型(多数快少数慢) | 快任务重跑、慢任务续跑,分治 |
一个容易被忽略的前置投资
三种策略都要用到同一个东西:结构化的失败记录(失败原因分类 + 上下文快照 + 可重放参数)。没有这个,无论选哪种策略,人工兜底的时候都在盲人摸象。批处理框架的第一行代码应该是失败日志的 schema,不是任务逻辑本身。
结语
恢复策略不是技术选型是风险选型:能承受多少重复执行(幂等性)、能承受多久延迟(时效性)、能承受多少人工介入(兜底成本)——三个维度定下来,策略自动浮现。这套实践来自我们做翻译工具批处理模块的踩坑记录,欢迎交流。
浙公网安备 33010602011771号