一样平常碰着这种情形下,在实时性哀求不高的场景我们有两种处理模式,一种是写任务定时推送数据同步到缓存中,另一个是下贱做事定时自动拉取。这两种模式都依赖做事自己的定时周期韶光,很多时候不好设定详细要多久实行一次,定时韶光太短在数据没有变革的时候会有很多无效的操作,如果定时韶光太长可能很多时候数据的延迟会比较大,某些时候影响也不好。
那有没有一种比较好的办法可以办理这个问题呢?答案当然是肯定的。本日就给大家先容一下 Canal,基于 MySQL 的 bin log 日志来实时监听数据变革。
官方的阐明是:canal,译意为水道/管道/沟渠,紧张用场是基于 MySQL 数据库增量日志解析,供应增量数据订阅和消费。

通过官方的阐明我们看到,是针对 MySQL 数据库增量日志解析的,MySQL 的日志是通过 bin log 的形式存储的二进制文件,供应数据订阅和消费便是说供应对二进制文件数据的监听。当日志数据发生变革的时候就会被监听到,从而程序就可以实时获取到有变革的数据。拿到变革的数据后就可以更新进缓存,ES 或发送到行列步队中关照下贱做事了。
事理上面先容了 Canal 的基本观点,现在我们看看 Canal是怎么实现的,我们都知道 MySQL 是支持主从同步的,而且 Slave 也是通过 bin log 日志的形式同步 master 实例数据的。以是 Canal 就奥妙的利用了这个事理,把自己仿照成一个 Slave,给 MySQL 的 master 发送 dump 协议,当 master 接管到 dump 协议的时候就以为 Canal 是一个 Slave 就会推送 bin log 给 Canal。
利用办法开启 MySQL 的binlogMySQL 的安装阿粉这里就不演示了,网上的文章一大把,大家可以自己去研究安装,假如 macOS 的话,终端里面输入brew install mysql 坐等搞定。
安装完成过后我们看下是否开启了 bin log ,如果没有开启则修正 my.cnf 增加 log-bin=mysql-bin 即可开启。输入命令mysql> show variables like 'log_bin'; 从图中我们可以看到阿粉这里是开启了 bin log 日志的。
接下来我们创建一个 canal 的账号,用于 canal 利用。我们创建一个 canal的账号,同时密码也是 canal。
CREATE USER canal IDENTIFIED BY 'canal'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON . TO 'canal'@'%';-- GRANT ALL PRIVILEGES ON . TO 'canal'@'%' ;FLUSH PRIVILEGES;
安装 Canal
这里我们安装 1.1.5 的版本,可以直接 wget https://github.com/alibaba/canal/releases/download/canal-1.1.5/canal.deployer-1.1.5.tar.gz 也可以在 GitHub 上面直接下载。
下载完解压后目录如图,我们须要修正配置文件,将账号密码以及 bin log 文件名配上
配置完成过后,通过 bin 目录下的脚本进行启动,并且通过日志我们可以看到启动成功。
做事端启动成功后,我们就须要利用客户端去获取数据了,这里我们可以参考 Canal 的 GitHub 官网中供应的 example 样例去进行仿照。
这里有个坑大家要把稳下,如果 MySQL 的版本是 8.0 以下该当没有这个问题,如果是 8.0 版本的,我们通过查看tail -f example.log 日志会创造如下非常Caused by: java.io.IOException: caching_sha2_password Auth failed。
阿粉这里就碰着了,经由在官方 GitHub 上面的 issue 中,如果搜索到干系的缺点信息 https://github.com/alibaba/canal/issues/1700,里面有大佬给理解决方案,在 MySQL 中实行如下命令即可办理
ALTER USER 'canal'@'%' IDENTIFIED BY 'canal' PASSWORD EXPIRE NEVER;ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';FLUSH PRIVILEGES;
如果没有碰着这个问题的小伙伴就可以直接忽略,接下来我们通过官方源码中的 example 示例来测试功能。把源码下载下来后找到com.alibaba.otter.canal.example.SimpleCanalClientTest 类,正常来说不须要修正什么内容,如果密码有变革的话这里可以调度,然后直接运行 main 函数即可。这个时候 MySQL,Canal,以及我们的测试类都已经启动了,下面通过实行 SQL 来创建数据库和表以及插入相应的数据,不雅观察掌握台的输出情形。
数据变更创建数据库mysql> create database canal_test;Query OK, 1 row affected (0.01 sec)mysql> use canal_test;Database changedmysql> show tables;Empty set (0.00 sec)
我们通过语句create database canal_test; 创建了数据库过后,可以看到掌握有如下输出,已经监听到了 bin log 的变革了。
创建测试表
再实行如下语句创建数据表
CREATE TABLE `example` ( `id` INT(11) NOT NULL ,`username` VARCHAR(32) DEFAULT NULL COMMENT '用户名称' ,` age` INT(11) DEFAULT 0 COMMENT '用户年事' ,` sex` INT(11) DEFAULT 0 COMMENT '用户性别 0 男 1 女' ,PRIMARY KEY (`id`))ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表';
可以看到成功的监听到了数据表的创建,接下来我们再试试插入数据和更新数据
## 插入语句INSERT INTO example VALUES(1,'张三', 18,0),(2,'李四', 19,0),(3,'王五', 20,1);## 更新语句update example set username = '张小三' where id = 1;
从上图中我们可以看到插入的数据以及更新的数据都被实时的监听到了。监听到数据过后,我们就可以根据事宜类型以及相应的库和表名来进行过滤操作了。对了,我们可以通过配置 filter 来过滤须要监听的数据库和数据表或者字段,这个都是可以实现的,避免无用的数据变更带来的影响。
对付访问 GitHub 很慢的小伙伴,阿粉已经帮大家把 Canal 的压缩包下载好了,"大众号回答【canal】即可获取网盘地址。
总结本日的文章给大家分享了 Canal 的利用,感兴趣的小伙伴可以自己去试试,如果须要的话,可以在项目中用起来,会事半功倍。