CDC 增量同步
基于数据库变更日志(如 MySQL binlog)实现增量数据捕获与跨库同步的技术方案,是实时数据链路的核心环节。
我的理解
CDC 的价值是让下游系统能实时消费上游变更,而不需要每次全量重跑。在物业数据智能场景里,canal、DataX 和 Flink CDC 都处理过。核心难点在于全量初始化与增量消费的业务主键对齐、字段拼接顺序一致性、失败重跑幂等性和压缩汇总正确性。
很多人以为 CDC 就是“监听 binlog 写到 Kafka”,跑通 demo 就以为搞定了。但生产环境里 CDC 的坑全在边界场景:全量初始化时业务主键和增量主键对不齐、字段拼接顺序变了导致下游解析错乱、失败重跑时重复消费产生脏数据、压缩汇总时漏了一条导致总数对不上。这些坑 demo 里根本遇不到。
我踩过的四个坑
这四个坑是我在物业数据智能项目里用真金白银买来的教训,每个都导致过线上事故。
- 全量与增量主键对齐:全量用业务主键、增量用 binlog row id,对不齐就丢数据
- 字段拼接顺序一致性:上游加字段后下游解析顺序错乱,整张表报废
- 失败重跑幂等性:重跑时重复消费产生重复数据,汇总值翻倍
- 压缩汇总正确性:增量压缩时漏了一条边界数据,看板总数对不上
为什么 CDC 比 ETL 更难
ETL 是批处理的,跑错了可以删了重跑。CDC 是流式的,数据一旦消费就难以回退。所以 CDC 的工程化重点不是“怎么同步”,而是“同步错了怎么恢复”——幂等性、断点续传、全量回灌预案,这些才是生产级 CDC 的核心。
4生产坑点
3技术方案
1幂等保证
0丢数据容忍
- 先选技术方案:canal 适合 MySQL binlog、Flink CDC 适合实时计算、DataX 适合全量补数据。
- 再定主键策略:全量和增量统一用业务主键,不要混用 row id。
- 然后做幂等设计:每条消息带版本号和操作时间戳,下游按主键+版本去重。
- 接着做断点续传:记录消费位点到可靠存储,重启时从位点继续而不是从头。
- 最后做全量回灌预案:增量链路断了时能快速切全量补数据,而不是手忙脚乱。
type CdcMessage<T = Record<string, unknown>> = {
op: 'INSERT' | 'UPDATE' | 'DELETE';
table: string;
primaryKey: string; // 业务主键(非 row id)
before: T | null; // 变更前数据
after: T | null; // 变更后数据
opTime: string; // 操作时间戳
txId: string; // 事务 ID(幂等去重用)
scn: number; // binlog 位点(断点续传用)
};| 维度 | canal | Flink CDC | DataX |
|---|---|---|---|
| 定位 | MySQL binlog 监听 | 实时计算+CDC 一体 | 批量全量同步 |
| 实时性 | 秒级 | 毫秒级 | 分钟级 |
| 适用场景 | 简单增量同步 | 实时数仓+计算 | 全量初始化+补数据 |
| 运维成本 | 中 | 高 | 低 |