简介
canal 的工作原理
MySQL 主从复制过程
➢ Master 主库将改变记录,写到二进制日志(binary log)中
➢ Slave 从库向 mysql master 发送 dump 协议,将 master 主库的 binary log
events 拷贝到它的中继日志(relay log);
➢ Slave 从库读取并重做中继日志中的事件,将改变的数据同步到自己的数据库。

canal 的工作原理
很简单,就是把自己伪装成 slave,假装从 master 复制数据
开始使用
前期准备
开启mysql的binlog
sudo vi /etc/mysql/my.cnf
[mysqld]
server-id = 1
log-bin=mysql-bin
binlog_format=row
binlog-do-db=gmall
参数说明
- 在[mysqld] ,log-bin=mysql-bin
这 个 表 示 binlog 日 志 的 前 缀 是 mysql-bin , 以后生成的日志文件就是
mysql-bin.123456 的文件后面的数字按顺序生成,每次 mysql 重启或者到达单个文件大
小的阈值时,新生一个文件,按顺序编号。
- mysql binlog 的格式有三种,分别是 STATEMENT,MIXED,ROW。
- binlog-do-db指定监控哪个数据库
配置好以后重启mysql
sudo systemctl restart mysqld
赋权限
mysql> set global validate_password_length=4;
mysql> set global validate_password_policy=0;
mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO
'canal'@'%' IDENTIFIED BY 'canal' ;
使用
canal 架构

下载
https://github.com/alibaba/canal/releases
主体配置
tar -zxvf canal.deployer-1.1.4.tar.gz
修改配置文件canal.properties
vi canal.properties
canal.serverMode = kafka
canal.mq.servers = master:9092,node1:9092,node2:9092
通过前面 canal 架构,我们可以知道,一个 canal 服务中可以有多个 instance,conf/
下的 每一个 example 即是一个实例 ,每个实例下面都有独立的配置文件。默认只有一个实
例 example,如果需要多个实例处理不同的 MySQL 数据的话,直接拷贝出多个 example,
并对其重新命名,命名和配置文件中指定的名称一致,然后修改 canal.properties 中的
canal.destinations=实例 1,实例 2,实例 3 。
canal.destinations = example
实例配置
修改 instance.properties
我们这里只读取一个 MySQL 数据,所以只有一个实例,这个实例的配置文件在
conf/example 目录下
vi instance.properties
配置连接 MySQL 的用户名和密码 ,默认就是我们前面授权的 canal
canal.instance.dbUsername=root
canal.instance.dbPassword=root
修改输出到 Kafka 的主题以及分区数
注意:默认还是输出到指定 Kafka 主题的一个 kafka 分区,因为多个分区并行可能会打乱
binlog 的顺序
# mq config
canal.mq.topic=gmall_db
# dynamic topic route by schema or table regex
#canal.mq.dynamicTopic=mytest1.user,mytest2\\..*,.*\\..*
#canal.mq.partition=0
# hash partition config,下面的分区数和自己主题的partition数目相同
canal.mq.partitionsNum=4
启动
bin/startup.sh
测试
bin/kafka-console-consumer.sh --bootstrap-server master:9092 --topic gmall_db
然后往mysql里面监听的数据库插入一条数据看kafka是否有数据接收到
停止
bin/stop.sh
canal 高可用
这种 zookeeper 为观察者监控的模式, 只能实现高可用,而不是负载均衡 ,即同一时点只
有一个 canal-server 节点能够监控某个数据源,只要这个节点能够正常工作,那么其他监控这
个数据源的 canal-server 只能做 stand-by ,直到工作节点停掉,其他 canal-server 节点才
能抢占。因为有一个 stand-by 也要占用资源,同时 canal 传输数据宕机的情况也比较少,所
以好多企业是不配置 canal 的高可用的。
接收到数据的格式例子
添加
{"data": [{"id": "1547090631092903951","user_id": "1413","nick_name": null,"head_img": null,"sku_id": "16","spu_id": "4","order_id": "5991","appraise": "1201","comment_txt": "评论内容:51811533721518964616668687831874922222995433369391","create_time": "2022-06-28 13:28:44","operate_time": null}],"database": "gmall","es": 1657690124000,"id": 211,"isDdl": false,"mysqlType": {"id": "bigint(20)","user_id": "bigint(20)","nick_name": "varchar(20)","head_img": "varchar(200)","sku_id": "bigint(20)","spu_id": "bigint(20)","order_id": "bigint(20)","appraise": "varchar(10)","comment_txt": "varchar(2000)","create_time": "datetime","operate_time": "datetime"},"old": null,"pkNames": ["id"],"sql": "","sqlType": {"id": -5,"user_id": -5,"nick_name": 12,"head_img": 12,"sku_id": -5,"spu_id": -5,"order_id": -5,"appraise": 12,"comment_txt": 12,"create_time": 93,"operate_time": 93},"table": "comment_info","ts": 1657690130536,"type": "INSERT"
}
删除
{"data": [{"dic_code": "1102","dic_name": "微信","parent_code": "11","create_time": null,"operate_time": null}],"database": "gmall","es": 1657690329000,"id": 212,"isDdl": false,"mysqlType": {"dic_code": "varchar(10)","dic_name": "varchar(100)","parent_code": "varchar(10)","create_time": "datetime","operate_time": "datetime"},"old": null,"pkNames": null,"sql": "","sqlType": {"dic_code": 12,"dic_name": 12,"parent_code": 12,"create_time": 93,"operate_time": 93},"table": "base_dic","ts": 1657690329374,"type": "DELETE"
}
修改
{"data": [{"id": "1","login_name": "g4hpd2mp2","nick_name": "修改","passwd": null,"name": "沈昌成","phone_num": "13973123428","email": "g4hpd2mp2@qq.com","head_img": null,"user_level": "1","birthday": "2004-08-10","gender": "M","create_time": "2020-06-10 21:48:29","operate_time": "2022-06-28 13:28:34","status": null}],"database": "gmall","es": 1657690400000,"id": 213,"isDdl": false,"mysqlType": {"id": "bigint(20)","login_name": "varchar(200)","nick_name": "varchar(200)","passwd": "varchar(200)","name": "varchar(200)","phone_num": "varchar(200)","email": "varchar(200)","head_img": "varchar(200)","user_level": "varchar(200)","birthday": "date","gender": "varchar(1)","create_time": "datetime","operate_time": "datetime","status": "varchar(200)"},"old": [{"nick_name": "雄琛"}],"pkNames": ["id"],"sql": "","sqlType": {"id": -5,"login_name": 12,"nick_name": 12,"passwd": 12,"name": 12,"phone_num": 12,"email": 12,"head_img": 12,"user_level": 12,"birthday": 91,"gender": 12,"create_time": 93,"operate_time": 93,"status": 12},"table": "user_info","ts": 1657690400556,"type": "UPDATE"
}