3步打通Kafka与MySQL双向同步:从数据孤岛到实时流动
你是否还在为MySQL数据同步延迟发愁?还在手动编写ETL脚本处理数据孤岛问题?本文将通过Kafka Connect实现MySQL与Kafka的双向实时同步,无需复杂代码,3个步骤即可完成从数据采集到写入的全流程搭建。读完本文你将掌握:
- 基于CDC的MySQL变更捕获技术
- Kafka Connect分布式部署最佳实践
- 数据一致性保障与冲突解决策略
- 性能调优与监控方案
一、同步架构解析:为什么选择Kafka作为中间件
传统数据同步方案常面临三大痛点:批量同步导致的延迟、自定义脚本维护成本高、跨系统数据一致性难以保障。Kafka作为高吞吐量的分布式消息队列,通过Kafka Connect组件可完美解决这些问题。
Kafka Connect提供两种核心连接器:
- Source Connector:从MySQL捕获变更数据(CDC)写入Kafka
- Sink Connector:从Kafka消费消息写入MySQL
双向同步架构如下:
官方文档详细说明了Kafka Connect的架构设计:Kafka Connect框架
二、环境准备:3个核心配置文件
2.1 Kafka Connect分布式配置
修改config/connect-distributed.properties文件,配置集群参数:
# 集群唯一标识
group.id=mysql-connect-cluster
# Kafka集群地址
bootstrap.servers=localhost:9092
# 偏移量存储主题
offset.storage.topic=connect-offsets
# 配置存储主题
config.storage.topic=connect-configs
# 状态存储主题
status.storage.topic=connect-status
# 插件路径(需包含JDBC和Debezium连接器)
plugin.path=/usr/local/share/java,/usr/local/share/kafka/plugins
2.2 MySQL源端配置
创建config/mysql-source.properties,配置CDC捕获:
name=mysql-source-connector
connector.class=io.debezium.connector.mysql.MySqlConnector
database.hostname=localhost
database.port=3306
database.user=kafka_user
database.password=kafka_password
database.server.id=184054
database.server.name=mysql-server
database.include.list=business_db
table.include.list=business_db.orders,business_db.users
# 启用GTID提高一致性
database.history.kafka.bootstrap.servers=localhost:9092
database.history.kafka.topic=schema-changes.business_db
# 变更事件格式
key.converter=org.apache.kafka.connect.json.JsonConverter
value.converter=org.apache.kafka.connect.json.JsonConverter
key.converter.schemas.enable=false
value.converter.schemas.enable=false
2.3 MySQL目标端配置
创建config/mysql-sink.properties,配置数据写入:
name=mysql-sink-connector
connector.class=io.confluent.connect.jdbc.JdbcSinkConnector
connection.url=jdbc:mysql://localhost:3306/business_db?useSSL=false
connection.user=kafka_user
connection.password=kafka_password
# 目标表配置
topics=mysql-server.business_db.orders,mysql-server.business_db.users
auto.create=true
auto.evolve=true
# 插入模式(upsert)
insert.mode=upsert
pk.fields=id
pk.mode=record_key
# 批处理优化
batch.size=1000
delete.enabled=true
三、分步实施:从部署到验证
3.1 启动Kafka Connect集群
# 后台启动分布式集群
nohup bin/connect-distributed.sh config/connect-distributed.properties &
# 检查集群状态
curl http://localhost:8083/connectors
Kafka Connect支持REST API管理,常用接口:
- 查看连接器列表:
GET /connectors - 创建连接器:
POST /connectors - 查看连接器状态:
GET /connectors/{name}/status
详细API文档见:Kafka Connect REST API
3.2 部署源端与 sink 连接器
# 部署MySQL源连接器
curl -X POST -H "Content-Type: application/json" --data @config/mysql-source.json http://localhost:8083/connectors
# 部署MySQL sink连接器
curl -X POST -H "Content-Type: application/json" --data @config/mysql-sink.json http://localhost:8083/connectors
其中mysql-source.json内容示例:
{
"name": "mysql-source-connector",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "localhost",
"database.port": "3306",
"database.user": "kafka_user",
"database.password": "kafka_password",
"database.server.id": "184054",
"database.server.name": "mysql-server",
"database.include.list": "business_db",
"table.include.list": "business_db.orders,business_db.users",
"database.history.kafka.bootstrap.servers": "localhost:9092",
"database.history.kafka.topic": "schema-changes.business_db",
"key.converter": "org.apache.kafka.connect.json.JsonConverter",
"value.converter": "org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": "false",
"value.converter.schemas.enable": "false"
}
}
3.3 数据同步验证
3.3.1 验证数据捕获
在MySQL中插入测试数据:
INSERT INTO business_db.users (id, name, email) VALUES (1, '测试用户', 'test@example.com');
通过Kafka消费者验证数据捕获:
bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic mysql-server.business_db.users --from-beginning
预期输出:
{
"before": null,
"after": {
"id": 1,
"name": "测试用户",
"email": "test@example.com",
"create_time": "2025-10-11 10:00:00"
},
"source": {
"version": "1.9.7.Final",
"connector": "mysql",
"name": "mysql-server",
"ts_ms": 1633941600000,
"snapshot": "false",
"db": "business_db",
"table": "users",
"server_id": 1,
"gtid": null,
"file": "mysql-bin.000001",
"pos": 154,
"row": 0,
"thread": null,
"query": null
},
"op": "c",
"ts_ms": 1633941600500,
"transaction": null
}
3.3.2 验证数据写入
通过Kafka生产者写入测试数据:
bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic mysql-server.business_db.orders
>{"id":100,"user_id":1,"amount":99.99,"status":"PAID","create_time":"2025-10-11 10:05:00"}
查询MySQL验证数据写入:
SELECT * FROM business_db.orders WHERE id = 100;
四、最佳实践:一致性与性能优化
4.1 数据一致性保障
-
** Exactly-Once语义 **:
# 在sink连接器中启用 exactly.once.support=true -
** 冲突解决策略 **:
- 时间戳优先:
upsert.mode=timestamp - 版本号控制:
transforms=AddVersion
- 时间戳优先:
-
** 分布式事务 **: 使用Kafka事务API包装多表操作
4.2 性能调优参数
| 参数 | 建议值 | 说明 |
|---|---|---|
tasks.max | CPU核心数*2 | 并行任务数 |
batch.size | 1000-5000 | 批处理大小 |
linger.ms | 50 | 批处理延迟 |
max.in.flight.requests.per.connection | 1 | 保证顺序性 |
详细调优指南见:Kafka Connect性能优化
4.3 监控与运维
-
** 关键指标 **:
- 连接器状态:
connector-status - 处理延迟:
record-processing-latency - 吞吐量:
records-per-second
- 连接器状态:
-
** 日志配置 **: 修改
config/connect-log4j2.yaml调整日志级别 -
** 故障恢复 **:
# 重启失败连接器 curl -X POST http://localhost:8083/connectors/mysql-source-connector/restart
五、常见问题与解决方案
5.1 数据延迟
现象:MySQL变更后Kafka消息延迟超过5秒
排查:
# 检查连接器任务状态
curl http://localhost:8083/connectors/mysql-source-connector/tasks/0/status
解决方案:
- 增加
tasks.max并行处理 - 调小
poll.interval.ms
5.2 数据不一致
现象:源表与目标表数据行数不匹配
解决方案:
- 启用
snapshot.mode=initial重新同步 - 检查主键定义是否正确
- 验证
pk.mode配置
5.3 连接器频繁重启
解决方案:
# 增加错误容忍度
errors.tolerance=all
errors.deadletterqueue.topic.name=dlq-connect
errors.deadletterqueue.topic.replication.factor=1
六、总结与进阶
通过Kafka Connect实现MySQL双向同步,我们既解决了传统ETL的延迟问题,又避免了自定义脚本的维护成本。生产环境中建议:
- ** 分阶段部署 **:先单向同步验证,再启用双向同步
- ** 灰度切换 **:新旧系统并行运行,逐步迁移流量
- ** 容灾设计 **:跨区域部署Kafka集群
进阶学习路径:
收藏本文,关注后续《Kafka与MySQL性能调优实战》,深入探讨亿级数据同步优化方案!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





