1. CDC 技术全景:实时数据产品的“心脏”

大家好,我是这次课程的主讲。在数据这个行当摸爬滚打了十几年,我见过太多系统因为数据同步不及时而“翻车”。今天咱们聊的 CDC,说白了就是解决这个问题的核心武器。

CDC,全称是 Change Data Capture,中文叫“变更数据捕获”。别被这个高大上的名字唬住,它的本质很简单:实时监听并捕获数据源的变更事件。你想想看,业务系统每时每刻都在产生数据——用户下单、修改资料、删除记录……CDC 就是那个趴在数据库上“偷听”的家伙,一旦有变化,它立刻就能感知到。

核心观点:CDC 不是简单的数据复制工具,它是连接 OLTP(在线事务处理)和 OLAP(在线分析处理)世界的桥梁。没有 CDC,实时数仓、实时报表、实时风控这些概念都只是空中楼阁。

1.1 为什么我们需要 CDC?

我记得刚入行那会儿,做数据同步全靠定时任务。每天凌晨跑一次批处理,把昨天的数据搬到数据仓库。那时候大家觉得“天级别的延迟”很正常。但现在呢?用户下单后 10 秒没看到订单状态更新,客服电话就打爆了。

CDC 的核心价值,我总结为三点:

  • 低延迟:从分钟级、小时级,直接降到秒级甚至毫秒级。我做过一个金融风控项目,要求交易发生后 500 毫秒内必须进入风控引擎。没有 CDC,这根本不可能。
  • 低侵入性:好的 CDC 方案对源系统几乎无影响。你不需要改业务代码,不需要停服,就能把数据实时同步出去。
  • 高可靠性:CDC 能保证数据不丢、不重。尤其是基于日志的方案,它记录的是数据库的“原始操作”,比业务层的逻辑更可靠。

我的经验:很多团队一开始用双写(业务代码里同时写两个库)来实现实时同步。结果呢?业务逻辑耦合严重,一旦同步失败,主库也跟着遭殃。CDC 的好处就是“解耦”——源系统完全不知道 CDC 的存在,它只管干自己的活。

1.2 CDC 的三种主流实现方式

CDC 的实现方式,业内公认的有三种。我挨个给你讲讲,每种我都踩过坑。

1.2.1 基于日志的 CDC(Log-Based CDC)

这是目前最主流、最推荐的方式。它的原理很简单:数据库本身就有事务日志(比如 MySQL 的 binlog、PostgreSQL 的 WAL、Oracle 的 Redo Log),CDC 工具直接读取这些日志,解析出数据变更事件。

为什么说它最好?

  • 性能影响极小:读取日志是数据库的常规操作,不会额外增加负载。我见过一个日活千万的系统,开启 binlog 后,QPS 下降不到 1%。
  • 捕获所有变更:包括 INSERT、UPDATE、DELETE,甚至 DDL 操作(比如加字段、删表)。
  • 无侵入性:不需要在业务表上加任何字段或触发器。

避坑指南:我曾经遇到过一个案例,MySQL 的 binlog 格式设置成了 STATEMENT 模式,结果 CDC 工具解析出来的数据全是 SQL 语句,根本拿不到变更前后的具体值。记住,一定要用 ROW 模式,才能捕获到每一行数据的完整变化。

1.2.2 基于触发器的 CDC(Trigger-Based CDC)

这种方式是在源数据库的表上创建触发器。当表发生 INSERT、UPDATE、DELETE 时,触发器自动把变更记录写入一张专门的日志表。CDC 工具再去读取这张日志表。

听起来挺合理,对吧?但实际用起来,问题不少:

  • 性能开销大:触发器是数据库内部的操作,会显著增加事务的执行时间。我做过压测,在高并发场景下,触发器会导致 TPS 下降 20%-30%。
  • 维护成本高:每次表结构变更,触发器也得跟着改。你想想,几百张表,每张表一个触发器,改起来多痛苦。
  • 容易丢数据:如果日志表写入失败,触发器不会回滚主事务,数据就丢了。

我的建议:除非你用的是不支持日志读取的老旧数据库(比如某些版本的 SQL Server),否则尽量别用触发器方案。它就像“用胶带修水管”——临时凑合可以,长期用肯定出问题。

1.2.3 基于时间戳的 CDC(Timestamp-Based CDC)

这种方式需要在业务表里加一个“最后修改时间”字段。CDC 工具定期执行查询,比如 SELECT * FROM orders WHERE update_time > last_check_time,来获取增量数据。

这是最“原始”的方式,也是问题最多的:

  • 无法捕获删除操作:记录都删了,时间戳自然也没了。除非你用“软删除”(加一个 deleted 字段),但很多业务系统不这么设计。
  • 时间精度问题:如果同一秒内有多条记录更新,时间戳一样,查询可能会漏掉或重复。
  • 对源库有压力:每次查询都是全表扫描(如果没建索引的话),对数据库性能影响很大。

我见过一个团队用这种方式做实时报表,结果每天凌晨跑批的时候,业务系统就卡死。后来一查,是时间戳查询把数据库 CPU 打满了。

对比维度 基于日志 基于触发器 基于时间戳
性能影响 极小(<1%) 较大(20%-30%) 中等(取决于查询频率)
数据完整性 完整(含 DELETE) 完整(含 DELETE) 不完整(不含 DELETE)
侵入性 无 高(需创建触发器) 中(需加时间戳字段)
维护成本 低 高 中
适用场景 所有实时场景 老旧数据库兼容 非关键、低并发场景

1.3 CDC 在实时数据产品中的核心价值

说了这么多技术细节,咱们回到业务层面。CDC 到底能帮我们解决什么问题?

  • 实时数仓:传统数仓 T+1 更新,CDC 让数据进入数仓的延迟降到秒级。你可以在数仓里直接查询“刚刚发生”的交易数据。
  • 实时报表与 BI:业务大屏上的数字不再是一小时前的快照,而是实时的。我做过一个电商大屏,订单量、销售额、库存数据全部通过 CDC 实时刷新。
  • 实时风控:金融行业最典型。用户一刷卡,风控系统必须在几百毫秒内判断这笔交易是否可疑。CDC 把交易数据实时推给风控引擎,才能做到“秒级响应”。
  • 数据迁移与同步:从 MySQL 同步到 Elasticsearch、从 Oracle 同步到 Kafka,CDC 是“零停机迁移”的核心技术。
  • 微服务间数据一致性:在微服务架构里,不同服务的数据往往分散在不同的数据库里。CDC 可以实时捕获一个服务的数据变更,然后同步给其他服务,实现“最终一致性”。

一句话总结:CDC 是实时数据产品的“心脏”。没有它,所有“实时”的承诺都是空话。你想想看,一个号称“实时”的推荐系统,如果数据延迟了 10 分钟,那推荐的结果可能已经过时了。

1.4 CDC 技术全景图

下面这张图,是我自己画的 CDC 技术全景。它把 CDC 的三种实现方式、核心组件以及下游应用串在了一起。你仔细看看,能对 CDC 的整体架构有个直观认识。

CDC 技术全景图 CDC 技术全景图 数据源 MySQL / PostgreSQL / Oracle 基于日志 (binlog/WAL) 基于触发器 基于时间戳 CDC 核心引擎 解析 / 过滤 / 转换 / 路由 消息队列 Kafka / Pulsar / RabbitMQ 实时数仓 ClickHouse / Doris / Hudi 实时风控 规则引擎 / 机器学习 实时搜索 Elasticsearch / Solr 数据同步 异构数据库迁移 💡 核心原则 低延迟 · 低侵入 · 高可靠

从这张图你能看到,CDC 的典型架构是:数据源 → CDC 实现方式 → CDC 核心引擎 → 消息队列 → 下游应用。消息队列在这里起到了“削峰填谷”的作用,让下游系统可以按自己的节奏消费数据。

我的习惯:在实际项目中,我通常会把 CDC 引擎和消息队列分开部署。引擎负责“读”和“解析”,消息队列负责“存”和“分发”。这样即使下游系统挂了,数据也不会丢——消息队列会帮你缓冲。

好了,这一章的内容就到这里。CDC 的全景图你已经看过了,三种实现方式的优劣也清楚了。接下来,我们会深入每一种实现方式,看看它们在实际项目中是怎么落地的。