跳转至

数据变更捕获与事件一致性

面试追问地图

主问题 必讲关键点 下一层追问
CDC 日志捕获、低侵入、异步传播 轮询与双写的区别
快照衔接 一致性位点、缓冲、回放 长事务和 DDL
Outbox 业务数据与事件同事务 发布重复、清理、积压
顺序幂等 key 分区、版本号、幂等 删除事件、乱序修复
迁移校验 数量、校验和、抽样、差异修复 切流与回滚

一、捕获与初始化

CDC 解决什么问题?

CDC(Change Data Capture)从数据库事务日志捕获已提交的行级变更,再发布到 Kafka、搜索、缓存或下游数据库。与应用同步双写相比,它不把两个远程系统塞进一次请求;与轮询业务表相比,它能保留更低延迟和更完整的变更顺序。

以 MySQL 为例,连接器读取 binlog 并保存位点。CDC 是至少一次链路:连接器在下游已接收但位点尚未持久化时宕机,恢复后会重复发送,所以消费者仍需幂等。

全量快照怎样无缝衔接增量?

新建同步任务通常先复制存量,再持续消费增量。关键是取得一致性快照及其日志位点:快照期间产生的变更先记录或缓冲,快照结束后从对应位点回放,避免“先查全表、过一会再读当前日志”中间的丢失窗口。

需要处理长事务、快照耗时、日志保留期和源库压力。DDL 可能改变事件 schema,应明确支持范围、停机变更窗口或兼容演进策略;不要把 DDL 当作普通行事件处理。

二、事务发件箱

事务发件箱怎样保证事件不漏?

业务写入和 Outbox 事件写入同一个本地数据库事务,CDC 或轮询发布器再把 Outbox 行发送到消息系统。这样消除了“数据库提交成功但消息发送失败”的双写窗口。

Outbox 保证的是可靠产生,不是端到端 exactly-once。发布后、标记完成前宕机会造成重复;事件 ID 用于消费者去重,aggregate ID 通常作为分区键维持同一聚合内顺序。还要治理表膨胀、发布延迟、失败重试和归档清理。

三、消费与校验

CDC 消费者怎样处理顺序和重复?

  • 同一业务实体按主键或 aggregate ID 分区,使相关事件进入同一有序分区。
  • 消费端保存事件 ID 或业务版本,用条件更新拒绝重复和旧版本覆盖新版本。
  • 删除事件要携带足够主键信息;软删除和物理删除的下游语义必须统一。
  • 反复失败的毒消息进入隔离队列,修复后按原 key 和版本约束重放。

全局顺序通常既昂贵又不必要,业务真正需要的是同一实体或聚合内顺序。

数据同步怎样证明正确?

上线前后都要做可重复校验:按分片比较行数、主键范围和聚合校验和,对不一致分片再逐行定位。抽样只能发现部分问题,不能作为唯一证据。切流时观察延迟位点和差异数量,保留旧链路与回滚窗口;修复任务也必须幂等,避免边修边产生新差异。

参考资料