2、Debezium架构总览:核心组件与事件流转
好,咱们正式进入Debezium的世界。这一章我会把它的骨架拆开给你看——核心组件有哪些,事件是怎么一路跑出来的,以及它和Kafka Connect到底是什么关系。
我个人习惯,学一个新东西先看整体架构图,脑子里有个地图,后面细节才不会迷路。来,先上图。
2.1 三大核心组件
Debezium 内部其实就干两件事:先拍一张快照,然后持续监听增量变化。这两个阶段分别由 Snapshot 和 Streaming 两个组件完成,而它们都跑在 Kafka Connect 的 Connector 容器里。
2.1.1 Connector —— 外壳与调度器
Connector 是 Kafka Connect 定义的接口。Debezium 实现了这个接口,把自己的逻辑包装进去。说白了,Connector 就是个调度器,它不干活,它负责分配任务。
- 任务分配:根据配置决定启动多少个 Task,每个 Task 负责一个数据库实例或分片。
- 生命周期管理:启动、停止、重启、重新平衡,都由 Kafka Connect 框架统一调度。
- 配置解析:把用户给的 JSON 配置转成内部可用的配置对象。
我的一点经验:很多人在配置 Debezium 时只配了 connector.class 和 database.hostname,却忽略了 tasks.max。默认 tasks.max=1,如果你的源库是分片集群,记得调大这个值,否则只有一个 Task 在干活,白白浪费并行能力。
2.1.2 Snapshot —— 初始快照
第一次启动时,Debezium 对数据库当前状态做一次全量快照。为什么需要这一步?因为 binlog 只记录增量,没有历史数据。你想想看,如果只监听 binlog,那之前的数据就永远拿不到了。
Snapshot 的工作流程大致如下:
- 获取全局锁(如果数据库支持),防止快照期间数据被修改。
- 记录当前 binlog 位置,确保后续 Streaming 能从正确位置开始。
- 逐表扫描,读取全量数据,每条记录生成一个 Change Event。
- 释放锁,切换到 Streaming 模式。
⚠️ 注意:快照期间如果表数据量很大,可能会对源库造成压力。我曾经在线上一个 2TB 的 MySQL 实例上跑快照,结果把主库的 IO 打满了。后来我改用 snapshot.mode=when_needed 配合增量快照,才把影响降到最低。
2.1.3 Streaming —— 增量流式
快照完成后,Debezium 自动切换到 Streaming 模式。它会持续连接数据库的变更日志(比如 MySQL 的 binlog、PostgreSQL 的 WAL),实时捕获 INSERT、UPDATE、DELETE 操作。
Streaming 的核心机制:
- 连接保持:与数据库建立长连接,通过心跳机制防止超时断开。
- 事件解析:把数据库原生的变更日志解析成结构化的 Change Event。
- 断点续传:记录已消费的 binlog 位置(offset),重启后从断点继续,不会丢数据。
关键点:Snapshot 和 Streaming 是串行执行的。先快照,再流式。但快照期间产生的增量变更不会丢失——Debezium 在快照开始时记录了 binlog 位置,快照结束后会从那个位置开始消费,把快照期间漏掉的变化补回来。
2.2 事件流转路径
一条数据从数据库变更到最终写入 Kafka,经历了哪些步骤?我画个流程图帮你理清楚。
嗯,这里要注意一个细节:事件构建这一步,Debezium 会生成一个 SourceRecord 对象。这个对象包含三个关键部分:
| 字段 | 说明 | 示例 |
|---|---|---|
| value | 变更后的数据(after)和变更前的数据(before) | {"before": null, "after": {"id": 1, "name": "Alice"}} |
| key | 主键或唯一键,用于 Kafka 分区路由 | {"id": 1} |
| source | 元数据,包含数据库名、表名、binlog 位置、时间戳等 | {"db": "mydb", "table": "users", "lsn": 12345} |
我建议:在生产环境中,尽量使用 Avro 序列化 + Schema Registry。JSON 虽然方便调试,但 schema 演化能力差。我曾经因为改了表结构没更新 schema,导致下游消费者反序列化失败,排查了半天才发现是字段类型不匹配。用 Avro 配合兼容性检查,这类问题基本能提前拦住。
2.3 与 Kafka Connect 的关系
很多人搞不清 Debezium 和 Kafka Connect 的区别。我直接说结论:Debezium 是 Kafka Connect 的一个插件,它不是一个独立运行的服务。
Kafka Connect 提供了:
- REST API 管理 Connector(创建、暂停、删除)
- 分布式协调(Worker 节点之间的任务分配)
- 偏移量管理(offset commit 和恢复)
- 连接器插件加载机制
Debezium 提供了:
- 数据库特定的变更日志读取逻辑
- 事件格式转换(SourceRecord 构建)
- 快照和流式切换的协调
说白了,Kafka Connect 是舞台,Debezium 是演员。舞台负责灯光、音响、幕布,演员负责把戏演好。
架构关系总结:
- Kafka Connect 以 Worker 进程 形式运行,可以单机(Standalone)或集群(Distributed)。
- Worker 加载 Debezium 的 JAR 包,通过 SPI 机制发现 Connector 实现类。
- 用户通过 REST API 提交配置,Kafka Connect 创建 Connector 实例,进而创建 Task。
- Task 内部运行 Debezium 的 Snapshot 或 Streaming 逻辑。
我记得有一次,团队里新来的同事直接对着 Debezium 的文档配了半天,发现怎么都启动不了。后来我一看,他根本没装 Kafka Connect,以为 Debezium 是个独立服务。嗯,这个坑其实挺常见的——Debezium 的官方文档默认你已经有 Kafka Connect 环境了。
⚠️ 避坑指南:如果你用 Docker 部署,记得把 Debezium 的 Connector 插件挂载到 Kafka Connect 容器的 /kafka/connect/ 目录下。我曾经图省事直接用了 Confluent Hub 安装,结果版本不匹配,Connector 加载失败。后来我改成手动下载对应版本的 JAR 包,再也没出过问题。
好,这一章我们把 Debezium 的骨架搭起来了。你脑子里应该有了这样一幅图:数据源 → Connector(外壳)→ Snapshot/Streaming(内核)→ Change Event → Kafka。后面几章,我们会逐个深入这些组件,看看它们内部到底是怎么工作的。