Yihui’s Blog

数据同步任务执行一半失败,如何保证数据一致性?

日期:2026-07-12
标签:#面试 #八股 #后端 #数据同步 #一致性 #场景题

一句话答案

采用小批次、检查点和幂等写入;每批目标提交成功后才推进源游标,失败从最后检查点重放,整批发布需求则使用 staging 与版本切换。

面试口语版

不能依赖一个覆盖全任务的超长事务。把任务按主键范围或日志位点分批,每条记录带业务主键和源版本,目标用 upsert/唯一键幂等。一个批次写目标成功后,再原子记录 checkpoint;若先记游标会漏数,后记游标最多重复。任务恢复时从最后完成 checkpoint 重放。若用户只能看到“全部新数据或全部旧数据”,先写 staging 表或新版本分区,全部完成、校验后原子切换可见版本,失败则丢弃未发布版本。

关键细节

  • checkpoint 包含源范围、目标批次、Schema 版本和校验信息。
  • 重试使用同一 batchId,避免重复产生副作用。
  • 目标部分成功时需要逐条幂等,或先清理该未提交批次。
  • 完成后对账条数、校验和和业务指标。

面试官追问

  1. 为什么游标必须在目标成功后提交?
  2. 如何实现全有或全无的可见性?
  3. 任务重跑时如何避免重复数据?

面试官追问参考答案

1. 为什么游标必须在目标成功后提交?

若先提交游标后目标写失败,恢复会跳过这批造成永久漏数;目标先成功再提交游标,故障最多导致重放。只要 Sink 幂等,重复比丢失更容易安全处理。

2. 如何实现全有或全无的可见性?

写入带版本的 staging 表/分区,读取端只看 activeVersion;任务全部完成并校验后原子切换版本指针或交换分区。旧版本保留回滚窗口,未完成版本不对用户可见。

3. 任务重跑时如何避免重复数据?

以业务主键加源版本 upsert,或对 batchId 建唯一约束;追加型目标保留事件 ID 并在读取/合并时去重。重跑必须使用相同输入边界和幂等标识。

学习清单

  • 掌握 checkpoint、幂等与版本发布。
  • 理解“至少一次 + 幂等”的恢复语义。
维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章