33.大批量任务的断点续跑:从“全量重跑”到“精确补偿”

大批量任务的断点续跑:从“全量重跑”到“精确补偿”

在离线任务、批处理、账务结算等场景中,“任务中途宕机了,从哪儿接着跑?”是绕不过去的问题。
如果每次都从头开始重跑,不但浪费资源,还可能引发业务超时。
真正的考点是:如何在保证数据正确的前提下,做到精准续跑

一、直觉方案:宕了就重跑一遍

最直观的做法是:

  • 任务挂了 → 重启服务 → 从头重新把所有数据跑一遍。

问题:

  1. 数据量大的场景几乎不可接受

    • 几千万条数据,每次异常都来一遍全量重算,成本极高。
  2. 时间不可控

    • 跑满一次全量的时间往往远超业务能接受的窗口。
  3. 完全浪费前面已成功的工作

    • 明明前 90% 已完成,却每次都要从 0 开始。

这种“无脑重跑”的策略,只适合作为最保守的兜底,不适合体面地出现在面试回答里。


二、核心思路:进度持久化 + 幂等保障

1. 进度持久化:用一张表记录“我处理到哪儿了”
  • 在数据库中建一张 progress 表,核心字段:

    • task_id:任务标识
    • offset:已经处理到的最后一条记录 ID 或偏移量
    • 其他如状态、更新时间等。
  • 每处理完一批数据(例如 1000 条),就更新一次 offset

    • 第一次:offset = 1000
    • 第二次:offset = 2000
  • 宕机重启后,启动逻辑变为:

    • 查询 progress 获取当前 offset;
    • 下次从 offset + 1 开始处理。

好处

  • 能够做到“从中间接着跑”,而不是从头开始。
2. 幂等保障:重复执行也不出错

即便有 offset,仍然有这种情况:

业务处理成功,但更新 progress 失败,重启后会重复处理这一批。

所以幂等性是刚需。典型做法:

  • 利用数据库唯一索引,重复插入直接被忽略。
  • 使用 INSERT IGNORE / ON DUPLICATE KEY UPDATE 等语法,保证多次执行结果不变。
  • 更新类操作设计为「幂等更新」:相同参数多次执行效果一致。

三、进度更新失败时如何权衡?

1. 默认策略:多处理一批,但结果不乱
  • 若处理数据成功,但 offset 更新失败:
    • 宕机重启后会从旧 offset 重复处理这一批数据。
    • 在幂等设计下:结果不乱,只是多耗一点计算资源。

这是一种以少量性能换可靠性的设计,非常常见。

2. 进一步优化:将业务处理与进度更新放入同一事务
  • 把“处理这一批数据 + 更新 offset”放到一个数据库事务中。
  • 要么两者一起成功,要么一起回滚。
  • 牺牲的是:
    • 单次批处理事务变大,锁定时间变长。
    • 但逻辑简单、状态更可控。

四、补充思路:批大小、重试与监控

在基础方案上,还可以从三个方向继续打磨:

  1. 合理控制批大小

    • 批太大会导致单次事务时间过长,对锁和日志不友好。
    • 批太小又会频繁更新 offset,增加开销。
  2. 为处理逻辑和 offset 更新增加重试

    • 例如:网络抖动导致写库偶发失败时可以重试一两次。
    • 重试仍失败时,记录错误日志供人工排查。
  3. 增加监控与告警

    • 监控任务耗时、进度推进速度、失败次数。
    • 避免“默默失败”,而业务方还以为任务已完成。

五、没有银弹,只有权衡

  • 单纯“全量重跑”过于粗暴,只能当兜底。
  • “进度持久化 + 幂等”是主流、务实的组合。
  • 是否要将进度与业务放到同一事务,要在性能与一致性之间做权衡。

六、面试思路

  1. 先抽象问题

    • 宕机后如何断点续跑?本质是“进度管理 + 幂等”。
  2. 给出核心方案

    • progress 表持久化 offset;
    • 每批处理完更新 offset;
    • 重启后从 offset+1 开始。
  3. 强调幂等

    • 利用唯一索引或 INSERT IGNORE 做幂等,避免重复执行导致结果错乱。
  4. 谈异常情况

    • 若任务成功但 offset 更新失败,会重复处理一批;
    • 代价只是性能浪费,不影响最终结果。
  5. 可以再加一层优化

    • 把“处理 + 更新进度”放到一个事务里,根据业务量权衡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值