一、 概述
工作需要研究了下阿里开源的MySQL Binlog增量订阅消费组件canal,其功能强大、运行稳定,但是有些方面不是太符合需求,主要有如下三点:
1、需要自己编写客户端来消费canal解析到的数据
2、server-client模式,需要同时部署server和client两个组件,我们的项目中有6个业务数据库要实时同步到redis,意味着要多部署12个组件,硬件和运维成本都会增加。
3、从server端到client端需要经过一次网络传输和序列化反序列化操作,然后再同步到接收端,感觉没有直接怼到接收端更高效。
go-mysql-transfer是使用Go语言实现的MySQL数据库实时增量同步工具, 参考Canal但是规避了上述三点。旨在实现一个高性能、低延迟、简洁易用的Binlog增量数据同步管道, 具有如下特点:
1、不依赖其它组件,一键部署
2、集成多种接收端,如:Redis、MongoDB、Elasticsearch、RocketMQ、Kafka、RabbitMQ,不需要再编写客户端,开箱即用
3、内置丰富的数据解析、消息生成规则;支持Lua脚本,以处理更复杂的数据逻辑
4、支持监控告警,集成Prometheus客户端
5、高可用集群部署
6、数据同步失败重试
7、全量数据初始化
二、 与同类工具比较
特色
Canal
mysql_stream
go-mysql-transfer
开发语言
Java
Python
Golang
HA
支持
支持
支持
接收端
编码定制
Kafka等
Redis、MongoDB、Elasticsearch、
RabbitMQ、Kafka、RocketMQ、
后续支持更多
数据初始化
不支持
支持
支持
数据格式
编码定制
json(固定)
规则(固定)
Lua脚本 (定制)
三、 设计实现
1、实现原理
go-mysql-transfer将自己伪装成MySQL的Slave,向Master发送dump协议获取binlog,解析binlog并生成消息,实时发送给接收端。
go-mysql-transfer原理
2、数据转换规则
将从binlog解析出来的数据,经过简单的处理转换发送到接收端。使用内置丰富数数据转换规则,可完成大部分同步工作。
例如将表t_user同步到reids,配置如下规则:
rule:
-
schema: eseap #数据库名称
table: t_user #表名称
column_underscore_to_camel: true #列名称下划线转驼峰,默认为false
datetime_formatter: yyyy-MM-dd HH:mm:ss #datetime、timestamp类型格式化,不填写默认yyyy-MM-dd HH:mm:ss
value_encoder: json #值编码类型,支持json、kv-commas、v-commas
redis_structure: string # redis数据类型。 支持string、hash、list、set类型(与redis的数据类型一致)
redis_key_prefix: USER_ #key前缀
redis_key_column: USER_NAME #使用哪个列的值作为key,不填写默认使用主键
t_user表,数据如下: