2、常见CDC技术选型:基于日志的CDC、基于触发器的CDC、基于时间戳的CDC、基于API的CDC
CDC 的技术选型,说白了就是选一把趁手的兵器。不同的业务场景,对数据延迟、侵入性、一致性要求都不一样。我这些年踩过的坑,大多是在选型阶段埋下的。今天咱们就把四种主流方案掰开揉碎聊一聊。
2.1 基于日志的CDC(Debezium、Canal)
这是目前生产环境里用得最多的方案。它的核心原理是读取数据库的事务日志(比如 MySQL 的 binlog、PostgreSQL 的 WAL),把数据变更解析成事件流。
Debezium 和 Canal 是这派的代表。Debezium 基于 Kafka Connect 生态,天生适合流式架构;Canal 是阿里开源的,专为 MySQL 设计,在 Java 生态里很成熟。
核心优势:对业务代码零侵入。你不需要改表结构,不需要加字段,更不需要写触发器。数据库自己就有日志,我们只是读一下。
我记得有一次帮一家电商公司做实时数仓。他们的订单表每天几百万条变更,如果用时间戳方案,凌晨跑批时数据对不上。后来上了 Debezium,延迟控制在秒级,而且 binlog 里记录了“前镜像”和“后镜像”,做数据回溯特别方便。
避坑指南:我曾经遇到过 binlog 格式没配成 ROW 模式,导致解析出来的数据全是 SQL 语句,根本拿不到字段值。记住,生产环境一定要用 ROW 格式。
不过日志方案也有短板:
- 对数据库有一定性能开销,尤其是大事务场景
- 需要维护日志消费位点,宕机恢复时要小心重复消费
- DDL 变更时,schema 同步是个麻烦事
2.2 基于触发器的CDC
触发器方案,就是在源表上建 INSERT、UPDATE、DELETE 触发器,把变更记录写到一张专门的日志表里。然后由另一个进程去读这张日志表。
说实话,这个方案我一般不太推荐。为什么?
- 触发器本身是数据库的隐式开销,每个 DML 都要多走一步
- 日志表容易成为热点,并发高时容易锁冲突
- 触发器逻辑和业务逻辑耦合,维护起来很痛苦
但也不是一无是处。我曾在某个金融项目里用过它——因为那家银行的 DBA 死活不给开 binlog,说安全审计过不了。没办法,只能用触发器。当时我们做了个优化:日志表按天分区,每天自动切换,避免单表过大。
注意:触发器方案会降低源库的写入性能,大约有 10%-30% 的损耗。如果业务对写入延迟敏感,慎用。
2.3 基于时间戳的CDC
这个方案最简单:在表里加一个 last_modified 字段,每次更新时写入当前时间。然后定时任务去查“时间戳大于上次拉取时间”的数据。
你想想看,这方案是不是很直观?很多初学 CDC 的人第一反应就是这个。但实际用起来,坑不少。
| 场景 | 问题 |
|---|---|
| 删除操作 | 时间戳字段不会记录删除,除非用软删除 |
| 时间精度 | 如果同一秒内有多条更新,可能漏数据 |
| 批量更新 | 大事务里时间戳相同,拉取时容易重复或遗漏 |
| 历史数据 | 无法获取变更前的旧值 |
我个人习惯只在两种场景下用时间戳方案:一是数据量小、对一致性要求不高的报表系统;二是作为日志方案的补充,比如做全量初始化。
2.4 基于API的CDC
这个方案是通过调用业务系统的 API 来获取数据变更。比如 SaaS 平台提供的 Webhook,或者自己写的 REST 接口。
它的好处是:不碰数据库,完全解耦。但坏处也很明显——你得让业务方配合改代码,每次新增字段都要改 API。
我遇到过最典型的场景是:一个老旧的 ERP 系统,数据库是 Sybase,连 binlog 都没有。我们只能让开发在业务代码里加一个 MQ 发送逻辑,每次增删改都往 Kafka 里丢一条消息。嗯,这其实也算一种 API 型 CDC。
小技巧:如果必须用 API 方案,建议让业务方把变更事件做成幂等的。这样即使消息重复消费,也不会影响数据一致性。
2.5 四种方案对比总览
下面这张图是我自己整理的选型决策框架,你可以直接拿去用。
2.6 我的选型建议
如果你问我怎么选,我的答案很简单:
- 能上日志方案,就上日志方案。Debezium + Kafka 是目前最成熟的组合,社区活跃,坑都被人踩过了。
- 如果数据库不支持 binlog(比如某些云数据库的只读实例),可以考虑 API 方案。
- 时间戳方案只适合做辅助,别把它当主力。
- 触发器方案,除非万不得已,别碰。
一句话总结:日志方案是 CDC 的“银弹”,但不是万能弹。选型时一定要结合你的数据库类型、网络环境、团队能力来综合判断。我见过太多人盲目跟风上 Debezium,结果被 schema 变更搞到崩溃。