1. Debezium 概述:CDC 概念、Debezium 架构、核心组件介绍
1.1 什么是 CDC?说白了就是“数据变,我就记”
CDC,全称 Change Data Capture,中文叫“变更数据捕获”。
你想想看,传统做法是怎么同步数据的?定时跑批,全量拉一遍。数据量小还行,一旦上了千万级,每次跑批都是对数据库的折磨。而且延迟至少几分钟到几小时,根本谈不上实时。
CDC 的思路完全不同——它只捕获变化的部分。插入、更新、删除,每一条变更都被记录下来,然后实时推送给下游。我习惯把 CDC 比作“数据库的日志订阅器”:你改了什么,我就知道什么,而且几乎零延迟。
CDC 的核心价值:
- 实时性高:毫秒级延迟,不是分钟级
- 对源库影响小:不锁表,不跑全量
- 数据一致性:基于日志,不会丢数据
CDC 的实现方式主要有两种:基于查询的(比如轮询时间戳字段)和基于日志的。Debezium 走的是后者——直接读取数据库的事务日志。我在项目中遇到过用轮询方式做 CDC 的,结果每次查询都压垮主库,后来换成 Debezium,问题就解决了。
1.2 Debezium 是什么?一个“日志翻译官”
Debezium 是一个开源的分布式 CDC 平台,基于 Apache Kafka 构建。它的核心工作就是:把数据库的变更日志,翻译成 Kafka 能理解的消息。
说白了,Debezium 就是数据库和 Kafka 之间的桥梁。你不需要写任何代码去轮询数据库,也不需要自己去解析 binlog。Debezium 帮你搞定一切。
我个人习惯把 Debezium 比作“数据库的实时镜像管道”:
源库每产生一条变更,Debezium 就把它变成一条 JSON 或 Avro 格式的消息,发到 Kafka 里。下游的消费者(比如 Elasticsearch、数据仓库、缓存)直接订阅 Kafka 主题就行。
1.3 Debezium 架构:三个核心角色
Debezium 的架构其实不复杂。我画了一张图帮你理解:
从图上你能看到,Debezium 架构主要分三层:
- 源数据库层:MySQL、PostgreSQL、MongoDB、Oracle、SQL Server 等。Debezium 通过读取各自的事务日志来捕获变更。
- Debezium 连接器层:这是核心。每个数据库类型对应一个连接器。连接器运行在 Kafka Connect 框架中,负责解析日志、生成事件。
- Kafka 消息层:事件被写入 Kafka Topic。下游系统通过订阅 Topic 来消费数据。
注意:Debezium 本身不存储数据,它只是“翻译”和“转发”。数据持久化依赖 Kafka。所以 Kafka 的稳定性直接决定了 CDC 管道的可靠性。我曾经因为 Kafka 集群磁盘写满导致 Debezium 任务挂掉,那叫一个惨——恢复后还要处理积压的 binlog。
1.4 核心组件详解
Debezium 的组件其实不多,但每个都很关键。我按重要程度给你捋一遍:
| 组件 | 作用 | 我踩过的坑 |
|---|---|---|
| Connector | 每种数据库的专属连接器,负责读取日志并生成事件 | MySQL Connector 需要开启 binlog_format=ROW,否则解析不了 |
| Kafka Connect | 运行连接器的分布式框架,提供 REST API 管理连接器 | 分布式模式下,连接器配置要小心 offset 存储,否则重启后重复消费 |
| Change Event | Debezium 输出的标准事件格式,包含 before/after 和元数据 | 默认 JSON 格式,字段名大小写敏感,下游解析时容易踩坑 |
| Snapshot | 连接器启动时对现有数据做一次全量快照 | 大表快照会占用大量资源,建议用 snapshot.mode=when_needed 控制 |
| Offset | 记录当前读取到的日志位置,用于故障恢复 | offset 存储在 Kafka Topic 或文件里,丢失会导致重复或丢失数据 |
1.5 一个典型的 CDC 事件长什么样?
嗯,这里要给你看个实际例子。Debezium 输出的 Change Event 是结构化的 JSON,包含几个关键部分:
{
"payload": {
"before": null, // 变更前的数据(INSERT 时为 null)
"after": { // 变更后的数据
"id": 1001,
"name": "张三",
"email": "zhangsan@example.com",
"created_at": "2024-01-15T10:30:00Z"
},
"source": { // 元数据:来自哪个库、哪个表、哪个位置
"db": "ecommerce",
"table": "users",
"server_id": 1,
"ts_ms": 1705300000000,
"file": "mysql-bin.000123",
"pos": 45678
},
"op": "c", // 操作类型:c=create, u=update, d=delete, r=snapshot
"ts_ms": 1705300001000 // 事件生成时间戳
}
}
我个人习惯:在生产环境中,我会把事件格式从 JSON 换成 Avro。虽然 Avro 需要 Schema Registry,但它的序列化效率高、schema 兼容性好,而且能避免 JSON 字段名大小写不一致的问题。
1.6 什么时候该用 Debezium?
不是所有场景都适合 CDC。我总结了几种典型场景:
- 实时数据同步:从 MySQL 同步到 Elasticsearch,实现搜索实时更新
- 缓存失效:数据库更新后,自动清除 Redis 缓存
- 数据仓库实时入仓:把业务库的变更实时写入 ClickHouse、Doris 等分析引擎
- 微服务事件驱动:一个服务修改数据后,通过 CDC 事件通知其他服务
避坑指南:我曾经在一个项目里,把 Debezium 用在了一个每天有 2 亿次写入的订单表上。结果 Kafka 的 Topic 分区数不够,消费者处理不过来,导致消息积压越来越严重。后来我调整了分区策略和消费者并发数,才把延迟降下来。所以,高吞吐场景下,一定要提前做好容量规划。
1.7 本章小结
这一章我们聊了 CDC 是什么、Debezium 怎么工作、以及它的核心组件。说白了,Debezium 就是帮你把数据库的变更日志变成实时数据流。你不需要写复杂的轮询代码,也不需要担心日志解析的细节。