软件研究之Canal
1.前言
数据同步工具,其实我用过很多,比如TIS,比如pci这个工具,还有DataX工具,最近在用 MySQL 数据库的时候,又找到了一个阿里开源的 Canal 数据同步工具。开始的时候我始终无法理解这个canal,还有 canal-adapter 和 canal-admin 到底是什么东西。经过我自己部署了一遍,查看了很多的文章,终于有了一定的理解。canal分为两部分,一部分是 server,一部分是 client 端。
Server端
Server端,其实就是Deployer服务,Deployer服务负责从上游拉取binlog数据、记录位点等。可以对外提供接口,供外部程序订阅,比如自己写的java程序。server代表一个canal运行实例,对应于一个jvm。一个server,可以包含多个instance实例。instance对应于一个数据队列 (1个server对应1..n个instance)。一个instance就是需要监听的数据库或者数据库表。Client端
Client端,就是Adapter服务,Client-Adapter服务负责对接Deployer解析过的数据,并将数据传输到目标库中。通过配置Adapter,可以监听Server中的某个实例,然后通过配置,同步到其他的数据库或者系统中,比如MySQL,Orcal、ES等。一个Adapter,可以配置监听多个instance,也可以将一个instance同时分发到多处,比如同时用日志打印和输出到数据库中。
【1】.超详细的canal入门,看这篇就够了 这篇文章其实用了java,自己写了一个监听器
【2】.常见数据同步工具之实时同步 1.Flume、Flink CDC。2.DataX CDC:复杂性:DataX CDC 的配置和使用相对复杂,需要熟悉 CDC 技术和相关的配置知识。4.Kettle:学习曲线较陡峭:尽管Kettle提供了图形化界面,但对于没有经验的用户来说,学习和掌握Kettle的各种功能和操作仍然需要一定的时间和精力。
【3】.canal配置mysql到mysql的数据同步
【4】.canal deployer 包 & canal adapter 包 参数详解
【5】.使用Canal同步MySQL数据 Deployer服务负责从上游拉取binlog数据、记录位点等。Client-Adapter服务负责对接Deployer解析过的数据,并将数据传输到目标库中。这里还有各个参数的具体说明,进入canal.adapter安装目录的conf路径下,编辑application.yml文件。
【6】.使用canal同步MySQL数据 安装了 canal-server,canal-apapter 和 canal-admin
2.canal-deployer
canal server 端,在仓库中是 canal.deployer 安装包。默认启动端口 :11111 端口。canal deployer 为 canal 标准包,可将其看做 canal server。它负责伪装成 mysql 从库,接收、解析 binlog 并投递到指定的目标端(RDS、MQ 或 canal adapter)
【1】.Canal-adapter的简单配置 HBase适配器、关系型数据库适配器、ElasticSearch适配器
2.1修改mysql配置
1 | # 编辑配置 |
2.2.创建用户
1 | mysql -u root -p |
2.3.安装
1 | # 访问 release 页面 , 选择需要的包下载 |
2.4.修改 canal 配置文件
可以通过
1 | cd /usr/local/canal/canal-deployer |
2.4.修改 instance 配置文件
1 | # 修改配置文件 |
2.5.启动
有些文章说要:检查lib目录下的jar包,一定要有对应的数据库驱动包,且版本要对得上,但是这部我没有做,也是可以正常启动和同步的。
1 | cd /usr/local/canal/canal-deployer/bin |
【1】.QuickStart 官方文档
【2】.Canal详细入门实战(使用总结) 1.Canal-deployer使用.2.Canal-adapter使用,我大部分的操作都是在这里做的。踩坑记录:数据库名不要使用下划线,一开始用canal_test_01的方式命名,发现扫描不到数据库。检查lib目录下的jar包,一定要有对应的数据库驱动包,且版本要对得上。
【3】.canal 同时监听两个数据库实例 1.复制一个example 并修改为example2。2.复制一个example 并修改为example2。3.在example目录中修改实例配置文件 instance.properties。4.在example2目录中修改实例配置文件 instance.properties。
【4】.阿里同步利器之canal使用案例
3.client-adapter
canal adapter 为 canal 的客户端,可将其看作 canal client。其中 RDB 包括 Oracle、MySQL、PostgreSQL、SQLServer 等数据库,目前Adapter具备以下基本能力:
- 对接上游消息,包括kafka、rocketmq、canal-server
- 实现mysql数据的增量同步
- 实现mysql数据的全量同步
- 下游写入支持mysql、es、hbase
3.1.下载
1 | # 下载 |
3.2.修改配置文件
1 | # 修改配置 |
3.3.配置表映射
在 conf/rdb 目录下,新建 .yml 结尾的配置,然后编写内容如下,如果有多个数据表需要同步,可以配置多个 .yml文件,如 example_1.yml,example_2.yml.
1 | # 配置rdb表映射 |
3.4.启动
有些文章说要:检查lib目录下的jar包,一定要有对应的数据库驱动包,且版本要对得上,但是这部我没有做,也是可以正常启动和同步的。
1 | # 在bin目录中启动canal-adapter |
【1】.基于canal的client-adapter数据同步必读指南 从1.1.1版本开始,canal实现了一个配套的落地模块,实现对canal订阅的消息进行消费,就是client-adapter(github.com/alibaba/canal/wiki/ClientAdapter)。目前的最新稳定版1.1.4版本中,client-adapter已经实现了同步数据到RDS、ES、HBase的能力。
4.canal-admin
【1】.canal web管理界面配置
【2】.Canal Admin 高可用集群使用教程
【3】.Canal 整合 canal-admin ,canal-adapter 创建canal-admin对应数据库,在代码里面有canal_manager.sql脚本。通过 ui 界面启动canal-server,增加canal -instance,以后通过canal-admin 修改配置文件,启动关闭服务,查看操作日志等等一系列操作。这里还有 targetColumns 部分表字段映射。
5.自启动
本来我想着能开机自动启动,后来发现好像没有人这么干过,网上的资料很少,我就放弃了。
【1】.canal开机自启动 这里用了 chkconfig –add canal 管理
5.docker
看到successful之后,就代表canal-server启动成功,可以启动canal-client链接上来进行binlog订阅了
6.配置多个
6.1.配置多个instance
(1) 在canal-server/conf/canal.properties 加入如下信息
1 | # 多个使用 逗号 分割 |
(2) 在 canal-server/conf 创建文件夹 example 和 example2
1 | conf |
(3) 修改不同的配置项,instance.properties
1 | canal.instance.master.address=192.168.1.23:3306 |
(4) 修改 canal-adapter/conf/application.yml 配置
1 | srcDataSources: |
(4)修改数据库映射配置
在rdb配置canal-adapter/conf/rdb下分别增加,相关的数据库配置.分别指向不同的 数据库和实例,example1.yml,example2.yml等。
1 | # 源数据库 |
【1】.canal第三篇:配置多个instance 在canal-server/conf/canal.properties 加入如下信息,多配置了多个instance,并且使用了 docker compose 进行配置。
7.增加配置
当上面的配置弄好了之后,双向同步也做好了,于是下一次需要增加同步的时候
(1)修改 canal-deployer/conf 中 instance 中监听表,canal.instance.filter.regex
(2)增加 canal-adapter/conf/rdb 中关于表的映射
不需要重启 canal-deployer 和 canal-adapter 这样就可以实现同步了。
问题
1.Unrecognized VM option ‘AggressiveOpts’
修改启动脚本,删除 AggressiveOpts 参数,
1 | JAVA_OPTS="$JAVA_OPTS -Xss1m -XX:+AggressiveOpts -XX:-UseBiasedLocking -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$base/logs" |
2.无法同步mysql
我搭建了 canal-deployer,搭建了 canal-adapter,配置了好几次,都无法完成映射,但是使用 logger,却可以打印日志。
【尝试方法】
(1)修改 targetTable 字段,结果无效。
(2)修改 rdp中conf/rdb/example.yml的配置destination,和conf/application.yml里面的配置 canalAdapters.instance 配置一致,文件名字也改成了一样。
(3)修改了rdb的配置 使用了 targetColumns。原本我是空的映射,后来改为了固定映射.
1 | # 原始 |
【解决方案】
最后我发现其实数据库更新了,不能同步,但是如果新增了一条记录,那就是可以同步的。也就是说,源数据库某条记录修改了,但是目标数据库相同主键记录不存在,虽然能打印日志,但是数据无法同步,只能修改相同主键信息的记录,才能实现同步。
【1】.canal-adapter同步mysql问题记录 这里有一个地方写错误了,就是 targetTable: mytest2.tb1 # 目标数据源的库名.表名,这里的 mytest2 是多余配置了。
【2】.canal adapter同步问题:部分字段数据没有同步 而在esMapping的配置中的sql我使用大写,虽然在mysql中对大小写不敏感,显示的也是期望结果。但是在adpater中无法识别这种情况,必须使用字段别名的方式。
【3】.canal-adapter字段过滤 如果表结构不一致的话,可以用targetColumns设置 : 从表字段名字: 主表字段名字
【4】.阮胜昌的技术记录站-LinuxMySQL数据库运维 如果表结构不一致的话,可以用targetColumns设置 : 从表字段名字: 主表字段名字
【5】.canal adapter没有同步成功无异常 适配器匹配原理分别对应:destination:config/xx/xxx.yml文件中的destination;groupId:config/xx/xxx.yml文件中的groupId;database: application.yml中srcDataSources.{xdb}.url中的database,如jdbc:mysql://10.0.0.10:3306/{database}?useUnicode=true;table:config/xx/xxx.yml文件中的sql中的表名
3.重新记录binlog值
重启之后,还是出现错误记录。在同步的时候,出现了一条记录某一个字段为空的问题:java.sql.SQLException: Field ‘create_time’ doesn’t have a default value,我想着把数据库里面的这条记录删除,但是我始终无法删除,因为我删除之后,就出出现,我重启了 canal,重启了canal-adapter,还是不行,问题到底出现在了哪里。
【解决方案】
先停止canal,把conf->example->meta.dat文件删除,在重启canal。重启会重新生成meta.dat文件,所记录的最新 binlog 文件和位置。
【1】.canal meta.dat引起数据同步问题 这里提到了删除 meta.dat 数据的方法。