一、 概述
=================
工作需要研究了下阿里开源的MySQL Binlog增量订阅消费组件canal,其功能强大、运行稳定,但是有些方面不是太符合需求,主要有如下三点:
1、需要自己编写客户端来消费canal解析到的数据
2、server-client模式,需要同时部署server和client两个组件,我们的项目中有6个业务数据库要实时同步到redis,意味着要多部署12个组件,硬件和运维成本都会增加。
3、从server端到client端需要经过一次网络传输和序列化反序列化操作,然后再同步到接收端,感觉没有直接怼到接收端更高效。
go-mysql-transfer功能对标canal,使用go语言编写,规避了上述三点。旨在实现一个简洁高效、稳定可靠的Binlog增量同步工具, 具有如下特点:
1、不依赖其它组件,一键部署
2、集成多种接收端,如:Redis、MongoDB、Elasticsearch、RocketMQ、Kafka、RabbitMQ,不需要再编写客户端,开箱即用
3、内置丰富的数据解析、消息生成规则;支持Lua脚本,以处理更复杂的数据逻辑
4、支持监控告警,集成Prometheus客户端
5、高可用集群部署
6、数据同步失败重试
7、全量数据初始化
二、 与同类工具比较
=================
![](https://static.studygolang.com/200904/e2d73ae65a114638d2f03cb306ac2f05.png)
三、 设计实现
=================
1、实现原理
go-mysql-transfer将自己伪装成MySQL的Slave,向Master发送dump协议获取binlog,解析binlog并生成消息,实时发送给接收端。
![go-mysql-transfer原理](https://upload-images.jianshu.io/upload_images/2897315-3b0fee8246d16250.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
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表,数据如下:
![](https://upload-images.jianshu.io/upload_images/2897315-4791c8c2db44e989.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
同步到Redis后,数据如下:
![](https://upload-images.jianshu.io/upload_images/2897315-9a29cbf41aecbfeb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
更多规则配置和同步案例 请见后续的"使用说明"章节。
3、数据转换脚本
Lua 是一种轻量小巧的脚本语言, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。开发者只需要花费少量时间就能大致掌握Lu