数据变更捕获与事件一致性¶
面试追问地图¶
| 主问题 | 必讲关键点 | 下一层追问 |
|---|---|---|
| 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 和版本约束重放。
全局顺序通常既昂贵又不必要,业务真正需要的是同一实体或聚合内顺序。
数据同步怎样证明正确?¶
上线前后都要做可重复校验:按分片比较行数、主键范围和聚合校验和,对不一致分片再逐行定位。抽样只能发现部分问题,不能作为唯一证据。切流时观察延迟位点和差异数量,保留旧链路与回滚窗口;修复任务也必须幂等,避免边修边产生新差异。