Canal实现缓存同步策略

发布时间 2023-10-19 17:41:59作者: 白布鸽

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主从同步的原理如下:
image

  • 1)MySQL master 将数据变更写入二进制日志( binary log),其中记录的数据叫做binary log events
  • 2)MySQL slave 将 master 的 binary log events拷贝到它的中继日志(relay log)
  • 3)MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

个人环境搭建

  1. 将docker mysql容器cnf配置文件修改一下,更改binary-log文件生成的地址以及文件名,其次是设置对哪个数据库进行监测binary-log文件。下面贴一下我的mysql配置文件中的内容,因为每个人的环境不一样,看一下就成。
    image
  • log-bin=/var/lib/mysql/mysql-bin:设置binary log文件的存放地址和文件名,叫做mysql-bin
  • binlog-do-db=heima:指定对哪个database记录binary log events,这里记录heima这个库
  1. 设置一个用于数据同步的用户,来让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容器
  1. 创建网络,需要创建一个网络,将MySQL、Canal放到同一个Docker网络中
docker network create lalala

让mysql容器和网络连在一起。

docker network connect lalala mysql
  1. 安装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=:要监听的表名称
  1. 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服务地址
  1. 让Canal知道怎么转换成实体对象
    这是我学习中项目代码,EntryHandler这个接口中三个对象分别是Insert update delete,其中@CanalTable("tb_item")代表的是让当前这个ItemHandler来监听哪个表产生变化,ItemHandler实现了上面的三个方法以后,数据产生更新就会对Redis和JVM进程缓存进行更新删除等操作。
    image
    在此之前可能还需要用到JPA的部分注解,@Id来表明当前实体的主键,@Column和表中的列做映射,@Transient来表明当前属性不作和表中列做对应。
    image
    至此,Redis和服务器内存缓存同步已经完成。