简述
Debezium 是一个开源的数据订阅工具,它可以捕获数据库的 CDC 变更数据发送到 Kafka。
为了实现将数据发送到其他数据库的目的,我们可以将 Kafka 中的数据,通过多种 Sink Connector 同步到 MySQL、Oracle、PostgreSQL、Starrocks 等。
本文以 MySQL -> Kafka -> Starrocks 为例,来演示 Debezium 同步数据到数仓的能力,并探讨如何构建一条稳定、高效的数据同步链路。
Debezium 环境准备
相关资源一键部署(Docker) 📎debezium-sync-my2sr.tar.gz
- Kafka 集群 + Kafka UI(中间件)
- Debezium(同步工具)
- MySQL(源端)
- Starrocks(目标端)
tar -xzvf debezium-test.tar.gz
sh install.sh
创建 MySQL Source Connector
- 源端是 MySQL,通过下面的表进行创建。
CREATE DATABASE `inventory`;
CREATE TABLE `inventory`.`customer` (
`c_int` int NOT NULL,
`c_bigint` bigint NOT NULL,
`c_decimal` decimal(10,3) NOT NULL,
`c_date` date NOT NULL,
`c_datetime` datetime NOT NULL,
`c_timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`c_year` int NOT NULL,
`c_varchar` varchar(10) NOT NULL,
`c_text` text NOT NULL,
PRIMARY KEY (`c_int`)
);
- 通过 Debezium 的 Api 接口创建 Connector 订阅 MySQL 的变更事件。
curl -i -X POST http://127.0.0.1:7750/connectors \
-H 'Content-Type: application/json' \
-d '{
"name": "connector-test-mx",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "112.124.38.87",
"database.port": "25000",
"database.user": "root",
"database.password": "123456",
"database.server.id": "1",
"database.server.name": "mx",
"database.include.list": "inventory",
"decimal.handling.mode": "string",
"binary.handling.mode": "hex",
"topic.prefix": "mx",
"table.include.list": "inventory.customer",
"snapshot.mode": "never",
"database.history.kafka.bootstrap.servers": "112.124.38.87:19092,112.124.38.87:29092,112.124.38.87:39092",
"schema.history.internal.kafka.bootstrap.servers": "112.124.38.87:19092,112.124.38.87:29092,112.124.38.87:39092",
"schema.history.internal.kafka.topic": "mx.schemahistory.customer",
"database.history.kafka.topic": "mx.mx_history_schema",
"include.schema.changes": "false",
"converters": "mysqltime",
"mysqltime.type": "io.debezium.converter.MySQLTimeConverter",
"mysqltime.format.date": "yyyy-MM-dd",
"mysqltime.format.time": "HH:mm:ss",
"mysqltime.format.datetime": "yyyy-MM-dd HH:mm:ss",
"mysqltime.format.timestamp": "yyyy-MM-dd HH:mm:ss",
"mysqltime.format.timestamp.zone": "UTC+8"
}
}'
- 创建后,查看 Connetor 的状态。
curl -s http://127.0.0.1:7750/connectors/connector-test-mx/status
创建 Sink Connector For Starrocks
- 目标端是 Starrocks,通过下面的表进行创建。
CREATE DATABASE `inventory`;
CREATE TABLE `inventory`.`customer` (
`c_int` int NOT NULL,
`c_bigint` bigint NOT NULL,
`c_decimal` decimal(10,3) NOT NULL,
`c_date` date NOT NULL,
`c_datetime` datetime NOT NULL,
`c_timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`c_year` int NOT NULL,
`c_varchar` varchar(10) NOT NULL,
`c_text` text NOT NULL
) ENGINE=OLAP
PRIMARY KEY(`c_int`)
DISTRIBUTED BY HASH(`c_int`) BUCKETS 4
PROPERTIES (
"replication_num" = "1",
"in_memory" = "false",
"storage_format" = "DEFAULT",
"enable_persistent_index" = "false",
"replicated_storage" = "true",
"compression" = "LZ4"
);
- 通过 Debezium 的 Api 接口创建 Sink Connector,将 Kafka 变更数据写入到 Starrocks。
curl -i -X POST http://127.0.0.1:7750/connectors \
-H 'Content-Type: application/json' \
-d '{
"name":"jdbc-sink-starrocks",
"config":{
"connector.class":"io.debezium.connector.jdbc.JdbcSinkConnector",
"connection.url":"jdbc:mysql://112.124.38.87:19030/inventory",
"connection.username": "root",
"connection.password": "123456",
"topics":"mx.inventory.customer",
"auto.create":"false",
"insert.mode": "insert",
"delete.enabled": "true",
"primary.key.mode":"record_key",
"primary.key.fields":"c_int",
"table.name.format": "inventory.customer"
}
}'
- 查看连接器的状态
curl -s http://127.0.0.1:7750/connectors/jdbc-sink-mysql/status
数据同步测试
- 将随机的增删改操作写入 MySQL 中,Debezium 会捕获 MySQL 的 CDC 变更数据并写入到 Kafka 中;Sink Connector 会将 Kafka 的数据写入到 Starrocks。
- 进行数据对比测试,两边数据一致
- 暂停 Debezium 的 Sink 任务
curl -i -X PUT http://127.0.0.1:7750/connectors/jdbc-sink-starrocks/pause
使用感受
Debezium 整体数据同步使用下来还是比较流畅的,社区也支持比较多的插件,生态丰富;但是其官方缺少消息到对端的能力(Sink 到其他数据库),这让一部分用户感觉束手无策。
我个人感觉比较适合开发来使用,并在 Debezium 的生态基础上接入到内部的业务系统中,但是对 DBA、运维不友好,且有一些问题不得不面对:
- 数据同步状态的把控(同步延迟、告警、监控)
- 数据同步的高可用(容灾恢复)
- 数据同步可视化(运维)
- 数据一致性对比及修复(数据准确)
能处理好以上这些问题,整个数据同步才能有一个比较好的保障,不然生产上线出了问题依靠社区也不能及时解决。最近我在调研有没有满足以上条件的数据同步产品,也是在 Starrocks 官方文档 上找到了一个数据同步工具 CloudCanal。
这个工具是使用上真的很 “傻瓜” ,用鼠标点击几下就可以创建一个数据同步任务,而且数据同步结束后可以直接校验两边的数据是否一致,不一致可立即修复。我部署到了本机 Mac 上作了测试,可以通过 CloudCanal 来消费 Kafka 的消息并同步到 Starrocks。
CloudCanal 订阅 Kafka 的数据变更
添加数据源
- 数据源管理 -> 添加数据源, 添加 Kafka、Starrocks、MySQL
创建同步任务
- 任务管理 -> 新建任务
- Kafka 选择 Debezium Envelope Json Format 格式
- Kafka 消息中如果有 Schema,需要在 任务详细 -> 参数修改 -> 源数据源配置 中修改 envelopSchemaInclude 为 true
测试同步
- 源端数据库做数据变更,Debezium 将数据写入 Kafka 后,CloudCanal 会写入到 Starrocks 中。
- 数据同步结束后校验 MySQL 和 Starrocks 的数据,40 万左右的数据是一致的。
总结
将两个数据同步产品进行打通也是比较有意思的事情,两者在数据同步领域各有特色,但 CloudCanal 更能满足我对数据同步的要求:
- 免费(喜欢白嫖)
- 可视化(低代码)
- 监控(同步指标、系统资源)
- 告警(短信、邮件、飞书、钉钉 等)
- 容灾(自动调度、组件隔离、数据修复)
- 社区支持(活跃)
我使用的仅仅是这个产品的冰山一角,更多的功能还需要再继续研究研究。
参考文档:
Debezium:https://debezium.io/documentation/reference/1.3/connectors/mysql.html
Kafka:https://kafka.apache.org/
Confluent:https://docs.confluent.io/platform/current/connect/index.html
CloudCanal:https://www.clougence.com/cc-doc/quick/quick_start
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。