环境准备:从零搭建实时同步基座
说实话,很多同学学 Debezium 卡住,不是因为概念难懂,而是环境没搭对。我见过太多人花了两天时间配置 MySQL Binlog,结果漏了一个参数,数据就是抓不到。这一章,咱们把地基打牢。
我会带着你一步步搞定四个核心组件:MySQL Binlog 配置、Zookeeper 部署、Kafka 集群搭建、Debezium Connector 安装。每个环节我都会告诉你「为什么这么做」,以及「我踩过的坑」。
本章核心目标:让你能在 30 分钟内,跑通一条完整的 CDC 链路——MySQL 产生变更 → Binlog 被捕获 → Kafka 收到消息。
2.1 MySQL Binlog 配置:开启数据捕获的开关
Binlog 是 MySQL 的二进制日志,记录所有数据变更。Debezium 就是靠读它来捕获数据的。我刚开始做 CDC 时,以为只要在 my.cnf 里加一行 log-bin=mysql-bin 就行,结果发现少配了两个参数,折腾了一下午。
下面是我验证过的配置,直接复制到你的 MySQL 配置文件(通常是 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf):
[mysqld]
# 必须:开启 Binlog
log-bin=mysql-bin
# 必须:Binlog 格式设为 ROW
binlog-format=ROW
# 必须:指定 MySQL 实例的唯一 ID
server-id=1
# 强烈建议:保留 Binlog 的天数
expire_logs_days=7
# 可选:Binlog 文件大小上限
max_binlog_size=1G
# 可选:记录所有数据库(可指定具体库)
binlog-do-db=your_database_name
⚠️ 我曾经踩过的坑:binlog-format 默认是 STATEMENT,Debezium 必须用 ROW 格式才能捕获到完整的数据变更。如果你用 STATEMENT,捕获到的可能是 SQL 语句而不是实际数据行,下游消费会出大问题。
配置完成后,重启 MySQL:
sudo systemctl restart mysql
验证 Binlog 是否开启:
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
mysql> SHOW BINARY LOGS;
+------------------+-----------+
| Log_name | File_size |
+------------------+-----------+
| mysql-bin.000001 | 154 |
+------------------+-----------+
看到 ON 和日志列表,说明 Binlog 已经跑起来了。
💡 我的建议:生产环境里,expire_logs_days 别设太大,7 天足够。否则磁盘会被 Binlog 撑爆。我见过一个案例,Binlog 保留了 30 天,结果磁盘满了,MySQL 直接挂了。
2.2 Zookeeper 部署:Kafka 的「大管家」
Zookeeper 是 Kafka 的协调服务。说白了,它负责管理 Kafka 集群的元数据、Leader 选举、故障转移。没有它,Kafka 集群就转不起来。
我个人习惯用单节点 Zookeeper 做开发和测试,生产环境至少 3 节点。这里先讲单节点部署。
步骤 1:下载并解压
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.8.1/apache-zookeeper-3.8.1-bin.tar.gz
tar -xzf apache-zookeeper-3.8.1-bin.tar.gz
cd apache-zookeeper-3.8.1-bin
步骤 2:配置 zoo.cfg
cp conf/zoo_sample.cfg conf/zoo.cfg
编辑 conf/zoo.cfg,核心参数如下:
| 参数 | 默认值 | 说明 |
|---|---|---|
| tickTime | 2000 | 心跳间隔(毫秒) |
| dataDir | /tmp/zookeeper | 数据存储目录,建议改到非临时路径 |
| clientPort | 2181 | 客户端连接端口 |
| initLimit | 10 | Leader 选举超时(tickTime 倍数) |
| syncLimit | 5 | Follower 与 Leader 同步超时 |
步骤 3:启动 Zookeeper
bin/zkServer.sh start
检查状态:
bin/zkServer.sh status
# 输出:Mode: standalone
💡 避坑指南:dataDir 别用默认的 /tmp/zookeeper,系统重启后数据会丢。我习惯用 /data/zookeeper,提前创建好目录并设置权限。
2.3 Kafka 集群搭建:消息的「高速公路」
Kafka 负责接收 Debezium 捕获的变更事件,并持久化到 Topic 中。下游消费者(比如 Flink、Spark、你的业务服务)再从 Topic 里拉取数据。
步骤 1:下载并解压
wget https://downloads.apache.org/kafka/3.4.0/kafka_2.13-3.4.0.tgz
tar -xzf kafka_2.13-3.4.0.tgz
cd kafka_2.13-3.4.0
步骤 2:配置 server.properties
编辑 config/server.properties,重点修改以下参数:
# 每个 Broker 的唯一 ID
broker.id=0
# 监听地址(0.0.0.0 表示所有网卡)
listeners=PLAINTEXT://0.0.0.0:9092
# Zookeeper 连接地址
zookeeper.connect=localhost:2181
# 日志保留时间(小时)
log.retention.hours=168
# Topic 副本数(单节点设为 1)
default.replication.factor=1
步骤 3:启动 Kafka
bin/kafka-server-start.sh config/server.properties &
验证 Kafka 是否正常运行:
# 创建一个测试 Topic
bin/kafka-topics.sh --create --topic test-topic --bootstrap-server localhost:9092 --partitions 1 --replication-factor 1
# 列出所有 Topic
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
看到 test-topic 出现在列表里,说明 Kafka 已经就绪。
⚠️ 注意:生产环境一定要设置 default.replication.factor 为 3,broker.id 不能重复。我曾经在测试环境忘了改 broker.id,两个 Broker 用同一个 ID,结果集群一直报错,折腾了半天才发现。
2.4 Debezium Connector 安装:CDC 的「翻译官」
Debezium Connector 是连接 MySQL 和 Kafka 的桥梁。它读取 Binlog,解析成结构化的变更事件,然后写入 Kafka Topic。
步骤 1:下载 Debezium MySQL Connector
wget https://repo1.maven.org/maven2/io/debezium/debezium-connector-mysql/2.3.0.Final/debezium-connector-mysql-2.3.0.Final-plugin.tar.gz
tar -xzf debezium-connector-mysql-2.3.0.Final-plugin.tar.gz
步骤 2:配置 Kafka Connect
Kafka Connect 是 Kafka 自带的连接器运行框架。编辑 config/connect-distributed.properties:
# 插件路径(指向 Debezium 解压目录)
plugin.path=/path/to/debezium-connector-mysql
# Kafka 集群地址
bootstrap.servers=localhost:9092
# 内部 Topic 配置
group.id=connect-cluster
key.converter=org.apache.kafka.connect.json.JsonConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
key.converter.schemas.enable=true
value.converter.schemas.enable=true
步骤 3:启动 Kafka Connect
bin/connect-distributed.sh config/connect-distributed.properties &
验证 Connector 是否加载成功:
curl http://localhost:8083/connector-plugins | jq .
返回结果里应该包含 io.debezium.connector.mysql.MySqlConnector。
步骤 4:注册 Debezium Connector
创建一个 JSON 配置文件 register-mysql.json:
{
"name": "mysql-connector",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "localhost",
"database.port": "3306",
"database.user": "debezium",
"database.password": "debezium",
"database.server.id": "1",
"database.server.name": "my-mysql",
"database.include.list": "your_database_name",
"database.history.kafka.bootstrap.servers": "localhost:9092",
"database.history.kafka.topic": "schema-changes.my-mysql"
}
}
注册 Connector:
curl -X POST -H "Content-Type: application/json" --data @register-mysql.json http://localhost:8083/connectors
检查 Connector 状态:
curl http://localhost:8083/connectors/mysql-connector/status | jq .
看到 "state": "RUNNING",恭喜你,CDC 链路已经通了。
🎯 验证整个链路:在 MySQL 里插入一条数据,然后消费 Kafka Topic:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic my-mysql.your_database_name.your_table_name --from-beginning
你应该能看到一条 JSON 格式的变更事件,包含 before、after、source 等字段。
2.5 环境验证清单
为了确保万无一失,我整理了一份检查清单。每完成一项,打个勾:
| 组件 | 验证命令 | 预期结果 |
|---|---|---|
| MySQL Binlog | SHOW VARIABLES LIKE 'log_bin'; | ON |
| Zookeeper | bin/zkServer.sh status | Mode: standalone |
| Kafka | bin/kafka-topics.sh --list ... | 列出 Topic |
| Kafka Connect | curl localhost:8083/connector-plugins | 包含 MySqlConnector |
| Debezium Connector | curl localhost:8083/connectors/mysql-connector/status | state: RUNNING |
💡 我的经验:如果 Connector 状态是 FAILED,别慌。先看日志:tail -f /tmp/connect.log。90% 的问题都是 MySQL 连接权限、Binlog 格式、或者 Kafka Topic 冲突。我曾经因为 database.server.name 重复,导致两个 Connector 往同一个 Topic 写数据,数据全乱了。
环境准备好了,接下来就可以真正开始使用 Debezium 了。记住,基础打牢了,后面才走得稳。