一、CDC概念与价值:为什么数据入湖离不开它
1.1 什么是CDC?说白了就是“只抓变化”
CDC,全称Change Data Capture,中文叫“变更数据捕获”。
我习惯这么跟团队解释:CDC就是数据库的“监控摄像头”——它只记录数据什么时候变了、变了什么、变成什么样了,而不是把整个数据库每天拷一遍。
举个例子。你的订单表有1000万行数据,每天新增2万行、修改5000行。如果用传统方式全量同步,每天得搬1000万行;用CDC,只需要搬那2.5万行变化的数据。你想想看,这效率差了多少?
CDC的核心定义:一种持续捕获数据源中新增、修改、删除操作的技术,并将这些变更以近乎实时的方式传递给下游系统。
常见的CDC实现方式有几种:
- 基于日志的CDC(我最推荐)—— 解析数据库的事务日志(如MySQL的binlog、PostgreSQL的WAL),对源库几乎无侵入
- 基于触发器的CDC —— 在源表上建触发器,捕获变更。嗯,这里要注意,触发器对数据库性能影响较大,我一般只在不得已时才用
- 基于时间戳的CDC —— 靠表中的“最后修改时间”字段来识别变化,简单但无法捕获删除操作
- 基于快照对比的CDC —— 定期全量对比,资源消耗最大,基本被淘汰了
1.2 为什么需要CDC?我踩过的坑告诉你
早些年做数据仓库,我经历过一次“血的教训”。
当时用每天凌晨的批量ETL同步订单数据,结果白天业务方发现某个订单状态已经变了6个小时,数据报表里还是旧状态。业务老大直接拍桌子:“你们数据团队是第二天才上班吗?”
从那以后,我对CDC的价值有了切身体会。说白了,CDC解决了三个核心痛点:
- 实时性 —— 数据变更后秒级甚至毫秒级就能同步到下游,不再是T+1
- 低负载 —— 只传输变化的数据,对源库和网络的压力都小得多
- 完整性 —— 能捕获所有变更操作,包括删除,保证数据链条不断
我的经验:在选型CDC方案时,先问自己三个问题:源库允许开binlog吗?对延迟的要求是秒级还是分钟级?下游能处理乱序数据吗?这三个问题想清楚,方案就定了七八成。
1.3 CDC与批量ETL的区别:不是一个维度的东西
很多人问我:“CDC是不是要取代ETL?”我的回答是:它们不是替代关系,而是互补关系。
| 对比维度 | 批量ETL | CDC |
|---|---|---|
| 同步频率 | 定时(如每天凌晨) | 持续(秒级/毫秒级) |
| 数据量 | 全量或大批量 | 仅变更数据 |
| 对源库影响 | 较大(全表扫描) | 极小(读日志) |
| 延迟 | T+1或小时级 | 秒级 |
| 捕获删除 | 需额外逻辑 | 天然支持 |
| 适用场景 | 历史数据批量加载、全量初始化 | 实时同步、增量入湖 |
我个人的做法是:先用批量ETL做全量初始化,再用CDC做增量实时同步。两者配合,既保证了数据完整性,又满足了实时性要求。
注意:CDC不是银弹。如果你的业务场景对数据一致性要求极高(如金融交易),CDC的“至少一次”或“恰好一次”语义需要仔细设计。我曾经在某个支付项目中,因为CDC的重复投递问题,差点导致对账不平——后来加了去重逻辑才解决。
1.4 CDC在数据湖中的定位:入湖的“最后一公里”
数据湖的核心理念是“存尽一切原始数据”。但问题来了——业务数据库的数据怎么进湖?
全量导入?每天几百TB的规模,带宽和存储都扛不住。这时候,CDC就成了数据入湖的标准答案。
在数据湖架构中,CDC扮演的角色是:
- 实时数据采集层 —— 从业务库捕获变更,写入消息队列(如Kafka)
- 增量数据管道 —— 将变更流转换为湖存储格式(Parquet/ORC)
- 数据一致性保障 —— 通过CDC日志回放,实现湖仓数据的最终一致性
下面这张图是我常用的CDC入湖架构,你可以直观地看到它的位置:
从这张图你能看到,CDC在整个数据入湖链路中处于承上启下的位置。上面连接业务数据库,下面对接消息队列和流处理引擎,最终把数据写入湖存储。
一句话总结:CDC是数据湖实时入湖的“水龙头”,没有它,数据湖就只能做T+1的离线分析,谈不上实时数据驱动。
1.5 什么时候不该用CDC?
说了这么多CDC的好处,我也得泼点冷水。不是所有场景都适合CDC:
- 数据量极小(每天几百条变更)—— 全量同步更简单,没必要上CDC
- 源库不支持日志(某些老旧的数据库)—— 硬上CDC反而得不偿失
- 对延迟不敏感(如月度统计报表)—— 批量ETL更省事
我见过不少团队盲目上CDC,结果运维成本比收益还高。记住:技术选型永远是为业务服务的。