← 返回题目列表

数据同步任务如何保证幂等?

中等 第 23 / 25 题 更新于 2026/10/04
数据同步幂等Checkpoint去重
学习 AI 实战项目

简化版

同步任务幂等的核心是稳定事件身份、目标端条件写和原子推进进度。 重复处理同一事件必须得到相同结果;旧版本事件不能覆盖新版本,删除用带版本墓碑。 Checkpoint 只在目标写入已确认后推进,并能处理“目标成功但确认丢失”的重复执行。

详细版

事件包含 eventId、entityId、sourceVersion、operation 和 sourcePosition。 目标表保存 lastSourceVersion,仅当 incomingVersion > lastSourceVersion 时才写。 对增量加法等非幂等动作,在同一事务插入 eventId 去重记录并更新业务数据。 多个分区分别维护有序 checkpoint,不能用一个全局 offset 跨分区确认。

完整版教学

一、为什么重复不可避免

至少一次投递、网络超时和 Worker 崩溃都会导致重放。 目标写成功后进程在提交 checkpoint 前退出,恢复后必然再处理。 正确系统把重复视为正常路径。

幂等不是尽量不重复,而是重复发生后结果不变。

二、事件身份

eventId: globally stable
entityId: O123
sourceVersion: 18
operation: UPSERT
sourcePosition: partition-3/offset-9001

重试沿用同一 eventId,不能每次重新生成。

三、状态覆盖同步

目标只在 incomingVersion 大于当前版本时覆盖。

输入当前动作
1918更新
1818重复,忽略
1718旧事件,拒绝

版本相同但内容不同应告警为源分叉。

四、增量动作去重

余额加 10 重复两次会加 20,不能只用覆盖。 在同一目标事务中先插入唯一 eventId,再执行增量。 唯一键冲突说明已处理,返回原结果。 去重记录与业务更新分两个事务仍有失败窗口。

五、Checkpoint 顺序

先写目标,再提交 source position。 先提交 offset 后写目标,崩溃会永久漏数据。 目标成功但 offset 未提交会重复,由幂等吸收。 每个 source partition 分别维护连续确认位置。

六、删除与全量

删除用 tombstone 和 sourceVersion,防迟到 upsert 复活。 全量同步可写 staging,校验后原子切换。 分页使用稳定主键游标,避免 offset 分页漏重。 runId 只是运行标识,业务幂等仍依赖实体版本或事件键。

七、观测验证

统计 received、applied、duplicate、stale、conflict 和 failed。 监控 checkpoint lag、最老未确认事件、版本跳跃和死信。 在目标提交前后分别杀进程,验证不漏且无重复副作用。 定期对账检测源事件缺失或映射错误。

八、常见误区与追问

  • 误区:MQ Exactly Once 让业务天然幂等。 外部数据库仍需事务与去重。
  • 误区:先提交 offset 更省事。 崩溃会永久漏数据。
  • 误区:所有操作都可用 upsert。 增量动作需要事件去重。
  • 误区:runId 就是业务幂等键。 批次重跑会变化。
  • 追问:成功响应丢失怎么办? 重放同一 eventId。
  • 追问:乱序怎么办? sourceVersion 条件写。
  • 追问:如何防删除复活? 保留带版本墓碑。

九、加强记忆

  1. 稳定 eventId 和 entityVersion。
  2. 覆盖写用版本 CAS。
  3. 增量写用事务内事件去重。
  4. 目标确认后再推进分区 checkpoint。
  5. 墓碑处理删除,对账补盲区。