通过 MySQL 提供的 Binlog,我们可以对 MySQL 中的数据进行同步;
本文总结了 Binlog 同步的两种方式:mysql-binlog-connector-java库、Canal组件;
源代码:
Java订阅Binlog的几种方式
目前主流订阅 MySQL Binlog 的方式有两种:
- 使用 osheroff/mysql-binlog-connector-java 库;
- 使用 alibaba/Canal 组件;
下面分别来看;
使用 mysql-binlog-connector-java 库
使用Docker部署MySQL并开启Binlog
mysql的binlog默认是不打开的,我们需要进行配置:
mysql/binlog/binlog-connector/config/mysqld.cnf
1 | [mysqld] |
将该配置文件挂载到 MySQL 配置路径中,并启动容器:
1 | docker run -itd --restart=always \ |
监测是否开启成功,进入mysql命令行,执行:
1 | mysql> show variables like '%log_bin%'; |
可以看到已经开启;
查看正在写入的binlog状态:
1 | mysql> show master status; |
代码读取binlog
下面我们引入 mysql-binlog-connector-java 依赖:
1 | <dependencies> |
然后根据官方提供的 Demo:
1 | public class Main { |
在实际使用时,可以在onEvent中写自己的业务逻辑;
在MySQL 中执行一些操作,输出:
1 | Event{header=EventHeaderV4{timestamp=0, eventType=ROTATE, serverId=1, headerLength=19, dataLength=28, nextPosition=0, flags=32}, data=RotateEventData{binlogFilename='mysql-bin.000003', binlogPosition=2862}} |
使用 Canal 组件
Canal介绍
早期的时候,阿里巴巴公司因为杭州和美国两个地方的机房都部署了数据库实例,但因为跨机房同步数据的业务需求 ,便孕育而生出了Canal,主要是基于trigger(触发器)的方式获取增量变更。从 2010 年开始,阿里巴巴公司开始逐步尝试数据库日志解析,获取增量变更的数据进行同步,由此衍生出了增量订阅和消费业务;
当前的 Canal 支持的数据源端Mysql版本包括( 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x)
Canal的工作原理
原理如下:
- Canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向MySQL master 发送dump 协议;
- MySQL master 收到 dump 请求,开始推送
binary log给 slave (也就是 Canal); - Canal 解析
binary log对象(数据为byte流);
基于这样的原理与方式,便可以完成数据库增量日志的获取解析,提供增量数据订阅和消费,实现mysql实时增量数据传输的功能;
使用Docker部署Canal
编写 docker-compose:
1 | version: '3.4' |
包括了 MySQL 和 Canal 两个服务;
和前面类似,MySQL 挂载的配置:
mysql/binlog/canal/config/mysqld.cnf
1 | [mysqld] |
启动容器:
1 | docker-compose up -d |
随后进入 canal 容器中修改配置:
1 | $ docker exec -it canal-canal-1 bash |
主要修改以下几行:
1 | # 修改为你的 MySQL 地址 |
注意这个:canal.instance.filter.black.regex 配置,如果不配置,会报错找不到表:
1 | Caused by: java.io.IOException: ErrorPacket [errorNumber=1146, fieldCount=-1, message=Table 'test.base table' doesn't exist, sqlState=42S02, sqlStateMarker=#] |
关联 issue:
代码集成Canal
添加依赖:
1 | <dependencies> |
示例代码:
mysql/binlog/canal/src/main/java/io/github/jasonkayzk/CanalDemo.java
1 | package io.github.jasonkayzk; |
启动服务后,执行 SQL 测试,输出日志:
1 | msgId -> 3 |
附录
源代码:
参考文章:
- https://juejin.cn/post/6844903889817321480
- https://juejin.cn/post/6844903894338764814
- https://blog.csdn.net/qq_18079589/article/details/120123733
- https://github.com/alibaba/canal/issues/4245