CDC 如何用于数据同步和最终一致性?
简化版
CDC 是 Change Data Capture,通过捕获数据库变更日志,例如 MySQL binlog,把数据变化同步到消息队列、搜索引擎、数据仓库或其他服务。它能降低业务代码侵入,但仍要处理顺序、重复、延迟、幂等和补偿问题。
详细版
CDC 常见流程:
- 业务系统正常写数据库。
- CDC 组件订阅数据库变更日志。
- 把 insert、update、delete 转成变更事件。
- 下游消费事件,同步到 ES、缓存、数仓或其他服务。
优点:
- 对业务代码侵入小。
- 能捕获真实提交后的数据变化。
- 适合异构数据同步,例如 MySQL 到 Elasticsearch。
风险:
- 同步有延迟。
- 事件可能重复。
- 多表事务和事件顺序要谨慎处理。
- 表结构变更可能影响下游。
- 仍需对账和补偿。
面试要强调:CDC 是最终一致手段,不是强一致方案。
完整版教学
一、CDC 解决什么问题
很多系统需要把数据库里的变化同步出去。例如商品信息写入 MySQL 后,要同步到 Elasticsearch 支持搜索;订单状态变化后,要同步到数仓做分析。
如果每个业务代码里都手写同步逻辑,会很侵入,也容易漏。CDC 直接读取数据库提交日志,把“数据库已经发生的变化”转成事件。
典型链路是:
业务写 MySQL -> binlog -> CDC 组件 -> MQ -> 下游系统
二、为什么 CDC 捕获的是已提交事实
数据库 binlog 记录的是事务提交后的变更。下游拿到 CDC 事件时,可以认为这次数据变化在源库已经成立。
这比“业务代码先发消息再提交事务”安全,因为不会出现事务回滚后下游收到假消息的问题。
但 CDC 事件到达下游仍然是异步的。源库已经变了,ES 可能几秒后才更新,所以它属于最终一致。
三、CDC 适合哪些场景
CDC 很适合数据投影和异构同步:
| 场景 | 说明 |
|---|---|
| MySQL 到 Elasticsearch | 搜索索引更新 |
| MySQL 到 Redis | 构建缓存或读模型 |
| MySQL 到数仓 | 实时分析 |
| 单体拆服务迁移 | 新服务同步旧库数据 |
它不适合要求下游必须和主流程强绑定成功的场景。比如支付成功后必须立即扣减某个强一致资源,不能只依赖 CDC 慢慢同步。
四、CDC 的重复和顺序问题
CDC 系统重启、位点回退、投递重试都可能导致重复事件。下游必须用主键、版本号、更新时间或事件位点做幂等。
顺序也要注意。同一行数据的更新顺序通常要保持,否则旧事件覆盖新事件会造成回退。
例如:
订单状态:WAIT_PAY -> PAID -> SHIPPED
如果下游先处理 SHIPPED,再处理延迟到达的 PAID,就会把状态覆盖回旧值。解决办法是使用版本号或状态流转规则,拒绝旧版本覆盖新版本。
五、表结构变更的影响
CDC 下游依赖源表字段。源表新增、删除、改名字段,都可能影响消费者。
所以 CDC 也需要 schema 演进管理:新增字段保持兼容;删除字段前确认下游不再使用;关键变更要通知消费者并灰度验证。
六、常见误区与追问
这道题要紧扣「CDC 数据同步与最终一致性」本身回答,不能把它混成泛泛的数据一致性套话。面试官通常会追问“写入怎么确认、失败怎么补、旧数据怎么防、成本在哪里”,所以回答要覆盖一致性目标、写入顺序、消息投递、幂等、补偿、对账和读写体验。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心结论 | CDC 通过捕获数据库提交日志生成变更事件,适合异构同步和读模型构建,但仍是最终一致方案 | 不要停在名词解释 |
| 流程机制 | 业务事务提交数据库 -> binlog 记录变更 -> CDC 读取位点 -> 转换为变更事件 -> 下游幂等消费 -> 对账补偿延迟或丢失 | 要说清触发点、状态变化、确认点和失败兜底 |
| 工程取舍 | MySQL 写入后 binlog 被 CDC 消费到 ES 可能延迟 1-3 秒,搜索结果短暂旧值是可预期的不一致窗口 | 一致性方案本质是在强一致成本、系统可用性、延迟和业务可接受的不一致窗口之间取舍 |
CDC 数据同步与最终一致性 面试拆解:
1. 业务事务提交数据库
2. binlog 记录变更
3. CDC 读取位点
4. 转换为变更事件
5. 下游幂等消费
6. 对账补偿延迟或丢失
记忆钩子:先给结论,再拆流程,再讲数字例子和失败边界;回答「CDC 数据同步与最终一致性」时要围绕题目问法收束,不要把相邻概念堆成一段没有重点的名词清单。
- 误区:CDC 可以替代强一致事务。 CDC 是异步同步手段,不能保证下游和主库在同一时刻强一致。
- 误区:读 binlog 就不会重复。 CDC 重启、位点回退和投递重试都可能让下游收到重复事件。
- 误区:表结构变更不会影响 CDC。 字段删除、改名和类型变化都可能让下游解析失败。
- 追问:CDC 为什么比业务双写更稳? 它基于数据库已提交日志,不会发出事务回滚后的假消息。
- 追问:如何处理乱序事件? 按主键维度保序,使用版本号、更新时间或 binlog 位点拒绝旧事件覆盖新值。
- 追问:CDC 仍要配什么兜底? 延迟监控、失败重试、死信、schema 管理、对账和补偿。
七、加强记忆
CDC 的核心是“读数据库变更日志,把已提交变化异步同步出去”。它侵入低、适合同步搜索和数仓,但本质仍是最终一致;重复、顺序、延迟、schema 变更和对账补偿都不能省。