1. CDC概念与场景:什么是CDC、为什么需要CDC、CDC的典型应用场景

大家好,欢迎来到这门课的第一章。

咱们直接切入正题——CDC。这三个字母,全称是 Change Data Capture,中文叫「变更数据捕获」。说白了,就是实时监听数据库里的数据变化,然后把变化抓出来,同步到别的地方去。

我刚开始接触这个概念时,觉得它不就是个「数据库触发器plus版」吗?后来踩了不少坑才明白——CDC 远不止这么简单。它解决的是分布式系统里最头疼的问题:数据怎么保持一致。

一句话总结:CDC 是数据管道的「耳朵」,专门听数据库的动静,一有变化就往外传。

1.1 什么是CDC?

想象一下这个场景:你的订单系统在 MySQL 里写数据,但数据分析团队要看实时报表,缓存要更新热点数据,搜索索引也要同步。总不能每次都去查 MySQL 吧?

CDC 的做法是——监听数据库的 binlog(二进制日志)。MySQL 每执行一条 INSERT、UPDATE、DELETE,都会在 binlog 里留下记录。CDC 工具(比如 Canal、Debezium)就盯着这个日志,一有动静就抓出来,转成统一格式,推给下游。

嗯,这里要注意:CDC 不是轮询。轮询是每隔几秒跑一次 SELECT * FROM table WHERE update_time > ?,效率低、延迟高、还容易漏数据。CDC 是事件驱动的,数据一变,立马通知。

对比维度 轮询查询 CDC 监听
实现方式 定时 SQL 查询 解析 binlog / WAL
延迟 秒级到分钟级 毫秒级
对源库影响 增加查询压力 几乎无影响
数据完整性 可能漏掉中间状态 完整记录每次变更
适用场景 离线批量同步 实时增量同步

我在项目中遇到过最典型的对比:某团队用轮询同步订单数据,每天凌晨跑一次,结果白天用户退款后,数据仓库里还是「已支付」状态,运营同学直接按错误数据发了促销邮件……后来换成 CDC,延迟降到 200 毫秒以内,再没出过这种问题。

1.2 为什么需要CDC?

你可能会问:我直接让业务代码双写(写数据库的同时写缓存、写ES),不也能同步吗?

理论上可以。但实际呢?

  • 耦合太深:业务代码里塞满各种同步逻辑,改一个下游系统就得改业务代码。
  • 一致性难保证:数据库写成功了,但写缓存失败了,数据就不一致了。重试?补偿?代码越来越复杂。
  • 性能损耗:每次写操作都要等所有下游都写完才返回,延迟飙升。

CDC 把这些问题都解耦了。业务只管写数据库,CDC 负责监听变化并推给下游。业务代码不用改,下游系统也不影响主流程。

我的建议:如果你正在设计一个新系统,一开始就把 CDC 考虑进去。别等到数据不一致了、同步延迟了再回头改造——那时候改造成本至少翻三倍。

还有一个更现实的原因:很多老系统改不动。我曾经接手过一个 10 年前的 Java 单体应用,代码里到处都是 JDBC 直连,连 ORM 都没用。想给它加个数据同步功能?改业务代码风险太大。最后就是在数据库层面挂了个 CDC 监听器,一周搞定,零代码侵入。

1.3 CDC的典型应用场景

CDC 能用的地方太多了。我挑三个最典型的讲讲。

场景一:数据仓库实时入仓

传统做法是每天凌晨跑 ETL,把业务库的数据全量拉一遍。但问题是——白天产生的数据,第二天才能看到。对于需要实时决策的业务(比如风控、实时大屏),这完全不可接受。

CDC 的做法是:业务库的数据一变化,就实时同步到 Kafka,然后由 Flink 或 Spark Streaming 消费,写入数据仓库。延迟从 T+1 降到秒级。

我记得有个电商客户,双十一当天需要实时监控每笔订单的支付状态。用 CDC + Kafka + Flink 的方案,数据从 MySQL 到 ClickHouse 的延迟稳定在 3 秒以内。运营同学在大屏上看到的数字,基本就是实时的。

场景二:缓存更新

缓存和数据库的一致性,是经典难题。常见的做法是「先更新数据库,再删除缓存」,但并发场景下还是可能读到旧数据。

CDC 提供了一种更优雅的方案:数据库更新后,CDC 捕获变更事件,推给缓存更新服务。缓存服务拿到最新数据后,直接更新 Redis 或本地缓存。整个过程不需要业务代码参与。

避坑提醒:我曾经遇到过 CDC 推送延迟导致缓存短暂不一致的情况。解决方案是给缓存加一个「版本号」,每次更新时对比版本号,旧版本不更新。这个小改动花了我半天时间,但彻底解决了问题。

场景三:微服务解耦

微服务之间怎么同步数据?最常见的是通过 RPC 调用。但服务多了,调用链就乱了。A 服务改了数据,要通知 B、C、D 服务,B 服务又要通知 E 服务……最后变成一张蜘蛛网。

CDC 的思路是:每个服务只管自己的数据库。数据变化通过 CDC 推送到消息队列,其他服务按需订阅。服务之间不再直接调用,而是通过数据事件来协作。

举个例子:订单服务改了订单状态,CDC 捕获到变更后,推给物流服务、支付服务、通知服务。每个服务各自处理,互不干扰。如果某个服务挂了,消息还在队列里,恢复后继续消费。

说白了,CDC 让微服务之间的数据同步变得「异步化、事件驱动、可追溯」。这也是 Event Sourcing(事件溯源)架构的基础。

1.4 CDC的核心流程

说了这么多,咱们用一张图把 CDC 的整体流程串起来。

CDC 增量同步核心流程 源数据库 MySQL / PostgreSQL binlog / WAL CDC 连接器 Canal / Debezium 消息队列 Kafka / Pulsar 下游消费者 数据仓库 缓存 Redis 搜索引擎 ES 其他微服务 数据流方向:源数据库 → binlog → CDC 连接器 → 消息队列 → 下游消费者 → 各目标系统

这张图把整个流程串起来了。你仔细看:数据从源数据库出发,经过 binlog、CDC 连接器、消息队列,最后到达各个下游系统。每个环节都有它的职责,缺一不可。

后面的章节,我们会一步步搭建这个管道。从环境准备、CDC 工具选型,到消息队列配置、下游消费,再到监控和运维,全部手把手带你过一遍。

嗯,第一章就到这里。CDC 的概念和场景,你应该已经心里有数了。接下来,咱们开始动手。