前阵子碰到一个需求,需要把MySQL里面的数据同步到ES。因为不想对业务代码有所侵入,所以就选择了通过Canal同步Binlog的方式,因此就对Canal粗略研究一番。
先简单介绍下什么是Canal,咱们就盗用官方的文档吧。canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。
要了解Canal工作原理,先要了解MySQL主备复制原理,咱们还是盗用下官方文档。
MySQL主备复制原理:
-
- MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
- MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
- MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
知道了MySQL主备复制原理后,我们再来看下Canal的工作原理。
Canal工作原理:
-
- canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
- MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
- canal 解析 binary log 对象(原始为 byte 流)
说一千遍,不如自己做一遍,撸起袖子就是干,咱们今天就把Canal在本地跑起来。
一般我拉源码都是取githup上面去拉,https://github.com/alibaba/canal ,下载下来后,导入开发工具,我用的idea,需要一个漫长的等待。
有些小伙伴在使用idea高版本的时候编译的时候会报错。
这个需要单独设置一下。
使用jdk 11及以上版本重新编译一下就ok。注意:idea版本越高,使用的JDK版本就越高,如果11不行,索性直接用19吧。
编译成功后,咱们来看下目录结构,这次的目标是把Canal的Admin和deployer给启动起来。
首先我们来启动Admin,Admin实质上就是一个Spring boot的应用,只要你知道 Spring boot怎么使用,问题应该不大。
- Admin的界面,如果你懂前端也可以去研究下
- 应用的启动入口
- 应用的配置,当然logback.xml也可以适当的调整下日志
关键还是看下application.yml文件,因为里面有我们所需要的信息
- Admin需要的数据库账号密码
- 后续deployer远程拉取时候会用到的账号密码
这里要说一下,配置Admin的数据库其实不需要完全依照配置文件里面的参数来,只要能连上并且有写权限就行。在启动之前,还需要到库里建表,建表语句已经给到我们了,顺便还会插入一条登录的账号密码数据。
好了,库建好了,表也建好了,配置也修改了,我们就可以启动Admin了。
启动报错,原来Admin使用了一个叫EBean的ORM框架,还需要EBean的插件,idea安装一下,安装完并启用后,重新启动成功,打开页面并登录,万里长征第一步。
坑爹啊,默认密码是Admin,但是页面又不允许少于6位,那只能改密码了。Admin在数据库中存储的是一个MD5加密后的数据。
但是在源码中也提供了加密方法,自己设置密码加密后修改数据库。
这下终于可以登录了。
就是这么简洁明了。Admin终于启动成功了,接下来就要启动deployer了。
通过启动文件得知,是通过CanalLauncher这个类启动。但是在启动之前,还需要配置一下Admin的地址。
好了进到CanalLauncher直接启动。发现并没有启动起来。
顺藤摸瓜,发现如果是配置了Admin地址,在启动的时候就会去请求Admin拉取配置。
实际请求的路径是Admin里面的。
最后会去查询数据库中是否存在对应的node节点。
那知道原因就很容易了,因为我们现在是单机,所以直接新建node节点就行。端口直接按照提示的输入就行。
新建好以后,再次启动deployer,查看Admin,显示已经启动了。
到这里,我们把Admin和单机版deployer启动了,后面就是新建Instance就能同步数据库了。
这里说一下,一个Server可以包含多个Instance,所以这里你可以新建多个Instance。
这次就到这里,下一次我们来看看集群模式是怎么启动的。后续我们分析源码也是基于集群模式。