1. CDC概念与原理:从数据变化说起

大家好,我是你们这门课的老朋友。今天咱们正式开篇,聊聊CDC——Change Data Capture,中文叫“变更数据捕获”。

说白了,CDC就是一套技术方案,用来实时或准实时地捕捉数据库里的数据变化(新增、修改、删除),然后把这些变化同步到其他系统里去。你想想看,现代数据架构里,数据源和目标端往往不是同一个库,怎么让它们保持数据一致?CDC就是那个“桥梁”。

核心一句话:CDC不是“全量搬运”,而是“增量同步”。它只关注“变了什么”,而不是“有什么”。

1.1 为什么需要CDC?——我在项目中踩过的坑

我记得刚做数据平台那会儿,团队还在用定时批处理脚本同步数据。每天凌晨跑一次全量抽取,跑完大概要两三个小时。业务方早上来一看,数据还是昨天的。后来业务要求实时性越来越高,批处理根本扛不住。

有一次,一个电商客户要求订单状态变更后5秒内同步到分析系统。我们试过用应用双写,结果代码改得一团糟,还经常漏数据。最后换成了CDC方案,问题才彻底解决。

所以,CDC的价值在哪?我总结了几点:

  • 低延迟:秒级甚至毫秒级捕获变化,满足实时场景
  • 无侵入:不需要改业务代码,对源库影响小
  • 高可靠性:基于日志的CDC能保证“至少一次”或“精确一次”的语义
  • 全量+增量一体化:先做一次快照,后续只同步增量,效率极高

我的经验:如果你还在用“定时全量覆盖”的方式做数据同步,赶紧看看CDC。尤其是数据量上了TB级别,全量抽取的成本会让你崩溃。

1.2 CDC的三种常见实现方式

CDC不是只有一种玩法。根据实现原理,我把它分成三大类。咱们一个一个说。

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

这是目前最主流、最推荐的方式。原理很简单:数据库的每一次数据变更,都会写入事务日志(比如MySQL的binlog、PostgreSQL的WAL、Oracle的Redo Log)。CDC工具直接读取这些日志,解析出变更事件,然后推送给下游。

我在项目中用得最多的就是这种方式。比如用Debezium监听MySQL的binlog,然后通过Kafka把变更事件流式传输到Lakehouse。

-- 示例:MySQL binlog中一条INSERT操作被解析成的事件结构(简化版)
{
  "op": "c",          -- c=create, u=update, d=delete
  "ts_ms": 1698000000123,
  "source": {
    "db": "ecommerce",
    "table": "orders",
    "server_id": 1
  },
  "before": null,
  "after": {
    "id": 10086,
    "user_id": 9527,
    "amount": 299.00,
    "status": "paid",
    "create_time": "2023-10-23 10:00:00"
  }
}

优点:对源库几乎无侵入,性能高,支持所有DML操作(包括DELETE)。
缺点:需要数据库开启日志功能,解析日志有一定技术门槛。

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

这种方式是在源库的表上创建触发器。当数据发生INSERT、UPDATE、DELETE时,触发器自动把变更记录写入一张专门的“变更日志表”。然后另一个进程去读取这张表,把数据同步出去。

嗯,这里要注意。我早期做过一个项目就是用触发器实现的。当时觉得挺简单,后来发现坑不少。

我曾经踩过的坑:触发器会显著增加源库的写入延迟,尤其是在高并发场景下。有一次生产环境因为触发器逻辑太复杂,导致数据库写入性能下降了30%。从那以后,我基本只在数据量小、对实时性要求不高的场景下才考虑触发器。

对比维度 基于日志 基于触发器 基于时间戳
对源库影响 低(异步读取日志) 高(同步触发) 低(仅查询)
支持DELETE 是 是 否(只能标记删除)
实时性 秒级/毫秒级 秒级 分钟级(取决于轮询频率)
实现复杂度 中高 低 低
适用场景 大规模、高并发、实时 小规模、低频、简单 非实时、无删除、可接受延迟

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

这种方式最“朴素”。在源表里加一个last_modified或update_time字段。同步程序定期轮询这张表,查询“时间戳大于上次同步时间”的数据,然后拉取增量。

说白了,就是“定时查表”。实现起来确实简单,但局限性也很明显。

我个人习惯:如果业务表本身就有update_time字段,而且数据量不大(百万级以内),用时间戳方式快速搭一个同步通道是可以的。但别指望它能处理DELETE操作——物理删除的数据,时间戳字段都没了,你查不到。

1.3 CDC在数据同步中的核心价值

讲完了实现方式,咱们聊聊CDC到底解决了什么问题。我把它归纳成三个层面:

  1. 实时性革命:从T+1到秒级。传统ETL是“定时批量”,CDC是“流式持续”。这个转变,让数据仓库从“事后分析”变成了“实时决策”。
  2. 数据一致性保障:基于日志的CDC能保证变更事件的顺序和完整性。不会丢数据,也不会乱序。这一点在金融、电商场景下至关重要。
  3. 架构解耦:源库不需要知道下游是谁。CDC工具作为中间层,把数据变更以统一格式(比如Debezium的Change Event)推送给Kafka、Pulsar等消息队列。下游的Lakehouse、实时计算引擎各取所需。

一句话总结:CDC让数据同步从“搬砖”变成了“管道”。你不需要每次把整栋楼的数据搬一遍,只需要把“变化的那几块砖”传过去就行。

1.4 一张图看懂CDC核心逻辑

下面这张SVG图,展示了CDC在数据同步中的整体流程。从源数据库到目标Lakehouse,CDC扮演了“实时搬运工”的角色。

CDC核心逻辑流程图 CDC核心逻辑流程图 源数据库 MySQL / PostgreSQL / Oracle CDC捕获机制 Binlog / Trigger / Timestamp 消息队列 Kafka / Pulsar 目标 Lakehouse Delta Lake / Iceberg / Hudi 数据变更 变更事件 流式写入 说明 CDC只捕获增量变化,不搬运全量

1.5 小结:CDC不是银弹,但它是基石

好了,这一章的内容就这些。CDC的概念和原理,说白了就是“怎么高效、可靠地捕获数据变化”。三种实现方式各有优劣,我个人强烈推荐基于日志的CDC作为首选方案,尤其是当你面对大规模、高并发的生产环境时。

下一章咱们会深入Debezium这个具体的CDC工具,看看它怎么和Kafka配合,把数据实时同步到Lakehouse。不过那是后话了,先把今天的基础打牢。

课后思考:如果你现在负责一个订单系统的数据同步,每天新增100万条订单,偶尔有更新和删除。你会选择哪种CDC方式?为什么?