前言
Canal 主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。
基于日志增量订阅和消费的业务包括
- 数据库镜像
- 数据库实时备份
- 索引构建和实时维护(拆分异构索引、倒排索引等)
- 业务 cache 刷新
- 带业务逻辑的增量数据处理
工作原理
Canal 将自己伪装成 MySql 从库,主库则会将binlog推送给从库(Canal)。
搭建
MySql 主库的搭建就不再写了,需要注意的是,必须开启binlog,且binlog格式为row或mixed。
Canal docker 安装
1.在主库中给Canal创建用户及分配权限
CREATE USER canal IDENTIFIED BY 'canal'; #创建用户名和密码都为 canal 的用户
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%'; #授予该用户对所有数据库和表的查询、复制主节点数据的操作权限
FLUSH PRIVILEGES; #重新加载权限
2.拉取 Canal 镜像
docker pull docker.io/canal/canal-server
3.启动canal,拷贝出配置文件至宿主机
#启动镜像
docker run -d --name canal canal/canal-server:latest
#拷贝配置文件
docker cp canal:/home/admin/canal-server/conf/canal.properties /home/docker/canal/conf
docker cp canal:/home/admin/canal-server/conf/test/instance.properties /home/docker/canal/conf
# 停止并删除容器
docker stop canal
docker rm canal
4.更改宿主机下的instance.properties配置项
canal.instance.mysql.slaveId=11 # 需要与主库serveId不一致
# position info
canal.instance.master.address=127.0.0.1:11111 // 数据库ip:port
# username/password
canal.instance.dbUsername=canal
canal.instance.dbPassword=Canal
# table regex
canal.instance.filter.regex=.*\\\\..\* # 需要监听的表
5.重启容器并绑定数据卷
docker run -p 11111:11111
--name canal
-v /home/docker/canal/conf/instance.properties:/home/admin/canal-server/conf/example/instance.properties
-d canal/canal-server:latest
-v 本地的instance.properties:容器的instance.properties 将容器的instance.properties配置文件挂载到宿主机,方便后续变更
6.查看日志是否有报错
docker logs 容器id
DOCKER_DEPLOY_TYPE=VM
==> INIT /alidata/init/02init-sshd.sh
==> EXIT CODE: 0
==> INIT /alidata/init/fix-hosts.py
==> EXIT CODE: 0
==> INIT DEFAULT
Failed to get D-Bus connection: Operation not permitted
Failed to get D-Bus connection: Operation not permitted
==> INIT DONE
==> RUN /home/admin/app.sh
==> START ...
start canal ...
start canal successful
==> START SUCCESSFUL ...
整合SpringBoot
1.引入依赖
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
2.配置yml文件
canal:
server: 127.0.0.1:11111 # Canal服务器地址和端口
destination: example # Canal Topic 默认 example
user-name: canal
password: canal
3.新建实体类
@Data
public class User implements Serializable {
private long id;
private String name;
private int age;
}
4.新建监听类,对某实体类的DDL变更监听
@Slf4j
@Component
@CanalTable(value = "user")
public class UserCanalListener implements EntryHandler<User> {
@Override
public void insert(User user) {
log.info("User_insert:{}", user.toString());
}
@Override
public void update(User before, User after) {
log.info("User_update_before:{}", before.toString());
log.info("User_update_after:{}", after.toString());
}
@Override
public void delete(User user) {
log.info("User_delete:{}", user.toString());
}
}
5.启动程序,在mysql中对数据进行更改
控制台打印:
User_update_before:User(id=1, name="La", age=11)
User_update_after:User(id=1, name="Hola", age=12)