Canal介绍
个人在学习Redis的过程中,遇到多级缓存的处理方法,我本人的多级缓存分类里面提到过个人学习中的项目构成。简单来说就是OpenResty集群负责缓存一些静态性比较强的数据,比如说这个网页上的分类信息等基本不变化的数据,而Redis和JVM进程缓存(使用Caffeine实现)负责缓存变化性比较大的数据资源。
话不多说,先介绍一下Canal,个人所学的内容是:它伪装成mysql的slave来时时刻刻获取master的Binary log这个文件,并将这文件中的内容返回到Canal客户端,继而进行Redis和JVM内存缓存的同步更新。
它是啥
Canal [kə'næl],译意为水道/管道/沟渠,canal是阿里巴巴旗下的一款开源项目,基于Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。GitHub的地址:https://github.com/alibaba/canal
Canal是基于mysql的主从同步来实现的,MySQL主从同步的原理如下:
- 1)MySQL master 将数据变更写入二进制日志( binary log),其中记录的数据叫做binary log events
- 2)MySQL slave 将 master 的 binary log events拷贝到它的中继日志(relay log)
- 3)MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
个人环境搭建
- 将docker mysql容器cnf配置文件修改一下,更改binary-log文件生成的地址以及文件名,其次是设置对哪个数据库进行监测binary-log文件。下面贴一下我的mysql配置文件中的内容,因为每个人的环境不一样,看一下就成。
log-bin=/var/lib/mysql/mysql-bin
:设置binary log文件的存放地址和文件名,叫做mysql-binbinlog-do-db=heima
:指定对哪个database记录binary log events,这里记录heima这个库
- 设置一个用于数据同步的用户,来让Canal伪装成slave“数据”。
- Navicat新建查询,运行以下命令。
create user canal@'%' IDENTIFIED by 'canal';GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%' identified by 'canal';FLUSH PRIVILEGES;
- 重启mysql容器
- 创建网络,需要创建一个网络,将MySQL、Canal放到同一个Docker网络中
docker network create lalala
让mysql容器和网络连在一起。
docker network connect lalala mysql
- 安装Canal
下面就是用docker pull镜像下来,然后安装了。
我是下面的命令:
docker run -p 11111:11111 --name canal \
-e canal.destinations=lalala \
-e canal.instance.master.address=mysql:3306 \
-e canal.instance.dbUsername=canal \
-e canal.instance.dbPassword=canal \
-e canal.instance.connectionCharset=UTF-8 \
-e canal.instance.tsdb.enable=true \
-e canal.instance.gtidon=false \
-e canal.instance.filter.regex=lalala\\..* \
--network lalala \
-d canal/canal-server:v1.1.5
-p 11111:11111
:这是canal的默认监听端口-e canal.instance.master.address=mysql:3306
:数据库地址和端口,如果不知道mysql容器地址,可以通过docker inspect 容器id
来查看-e canal.instance.dbUsername=canal
:数据库用户名-e canal.instance.dbPassword=canal
:数据库密码-e canal.instance.filter.regex=
:要监听的表名称
- boot那边需要添加依赖和配置如下:
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
canal:
destination: lalala # canal的集群名字,要与安装canal时设置的名称一致
server: 192.168.25.128:11111 # canal服务地址
- 让Canal知道怎么转换成实体对象
这是我学习中项目代码,EntryHandler这个接口中三个对象分别是Insert update delete,其中@CanalTable("tb_item")代表的是让当前这个ItemHandler来监听哪个表产生变化,ItemHandler实现了上面的三个方法以后,数据产生更新就会对Redis和JVM进程缓存进行更新删除等操作。
在此之前可能还需要用到JPA的部分注解,@Id来表明当前实体的主键,@Column和表中的列做映射,@Transient来表明当前属性不作和表中列做对应。
至此,Redis和服务器内存缓存同步已经完成。