Canal Java 入门与使用
0、前言
在如今时代数据是最关键的,大的数据量势必会影响用户体验,在我的日常开发中遇到了一个类似的问题,由于数据库中数据量过于庞大造成查询效率低,决定采用redis来存取最新的数据,由于系统为其它语言编写本人并不擅长,便采取canal来通过增量的方式更新数据。下面让我们了解一下canal。
1、什么是canal
- canal 直译为管道、渠道、水道,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。
以上介绍来自于官网介绍。我们可以简单把canal理解为一个同步增量数据的工具。
上图为官方给出的示意图,可以看到canal把自己伪装成一个mysql的slave,架起了MySQL与其他软件之间的桥梁。
canal的工作原理就是把自己伪装成MySQL slave,模拟MySQL slave的交互协议向MySQL Mater发送 dump协议,MySQL mater收到canal发送过来的dump请求,开始推送binary log给canal,然后canal解析binary log,再发送到存储目的地,比如MySQL,Kafka,Elastic Search等等。
2、canal能做什么
canal能做什么换个说法就是数据同步有什么用?
由于canal数据同步不是全量同步,而是增量同步。基于binary log增量订阅和消费,canal可以做:
- 数据库镜像
- 数据库实时备份
- 索引构建和实时维护(拆分异构索引、倒排索引等)
- 业务 cache 刷新
- 带业务逻辑的增量数据处理
注释:Binary log为数据库二进制文件主要记录所有数据表结构变更以及修改的二进制日志。
3、如何使用canal
3.1首先你要有一个数据库
当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x
MySQL安装可以查看之前的文章:
3.1.1创建用户
然后需要在MySQL中添加一个用户用于数据同部使用,并授予相关表权限
-- 使用命令登录:mysql -u root -p
-- 创建用户 用户名:canal 密码:Canal@123456
create user 'canal'@'%' identified by 'canal';
-- 授权 *.*表示所有库
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%' identified by 'canal';
3.1.2修改配置文件
在MySQL的配置文件my.cnf中添加如下配置
[mysqld]
# 打开binlog
log-bin=mysql-bin
# 选择ROW(行)模式
binlog-format=ROW
# 配置MySQL replaction需要定义,不要和canal的slaveId重复
server_id=1
3.1.3检查配置是否生效
修改完成配置后重启MySQL服务,使用命令检查配置是否生效,
查看是否打开binlog模式
show variables like 'log_bin'
查看binlog日志文件列表
show binary logs
查看当前正在写入的binlog文件
show master status
到此MySQL配置已经全部搞定,暂时告一段落。
3.2安装cancal
3.2.1下载canal
可以从官网下载:https://github.com/alibaba/canal/releases
(可能需要加速)
下载下图圈出版本即可。
cd /usr/local/canal
ls
tar -zxvf canal.deployer-1.1.4.tar.gz
下载完成后上传服务器,解压缩到自己喜欢的路径即可,接下来需要对canal进行配置
3.2.2配置canal
打开配置文件conf/example/instance.properties,其中需要修改内容如下:
# 数据库地址
canal.instance.master.address=127.0.0.1:3306
# binlog日志名称
canal.instance.master.journal.name=mysql-bin.000001
# mysql主库链接时起始的binlog偏移量
canal.instance.master.position=154
# 在MySQL服务器授权的账号密码
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
# 以下修改能容可选
# table regex .*\\..*表示监听所有表 也可以写具体的表名,用,隔开
canal.instance.filter.regex=.*\\..*
# mysql 数据解析表的黑名单,多个表用,隔开
canal.instance.filter.black.regex=
配置完成后保存文件
3.2.3运行canal
进入bin目录
./startup.sh
这样就成功启动canal了。
注意
canal默认占用端口11111客户端如果想要连接canal服务需要在Linux中开放11111端口
//开启端口
firewall-cmd --zone=public --add-port=11111/tcp --permanent
//查询端口号11111是否开启:
firewall-cmd --query-port=11111/tcp
//重启防火墙:
firewall-cmd --reload
//查询有哪些端口是开启的:
firewall-cmd --list-port
//禁用端口
firewall-cmd --zone=public --remove-port=11111/tcp --permanent
3.3建立canal客户端
3.3.1引入依赖、修改配置
Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。不过这里我们会使用GitHub上的第三方开源的canal-starter。地址:https://github.com/NormanGyllenhaal/canal-client
引入依赖:
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
编写配置文件
canal:
destination: example # canal实例名默认为example可以在配置文件中修改
server: 192.168.0.5:11111
3.3.2编写监听器
@CanalTable("history_log") //需要监听的表
@Component
public class HistoryLogHandler implements EntryHandler<HistoryLog> {//指定表关系实体类
@Override
public void insert(HistoryLog historyLog) {
//新增数据时执行此方法
}
@Override
public void update(HistoryLog before, HistoryLog after) {
//更新数据时执行此方法
}
@Override
public void delete(HistoryLog historyLog) {
//删除数据时执行此方法
}
}
4、总结
canal的好处在于对业务代码没有侵入,因为是基于监听binlog日志去进行同步数据的。实时性也能做到准实时,其实是很多企业一种比较常见的数据同步的方案。
通过上面的学习之后,我们应该都明白canal是什么,它的原理,还有用法。实际上这仅仅只是入门,因为实际项目中我们不是这样玩的…
实际项目我们是配置MQ模式,配合RocketMQ或者Kafka,canal会把数据发送到MQ的topic中,然后通过消息队列的消费者进行处理。
Canal的部署也是支持集群的,需要配合ZooKeeper进行集群管理。
Canal还有一个简单的Web管理界面。如果有想看的可以留言告诉我我再写一篇文章。
如果你也喜欢这篇文章,或者对这篇文章有其他见解欢迎留言交流。
一句话与大家共勉:君子慎独,不欺暗室。 卑以自牧,含章可贞。