SpringBoot整合Canal进行数据库 缓存同步
Canal 是阿里巴巴开源的一款基于 MySQL 数据库的增量日志订阅和解析工具,主要用于实现数据的实时同步和流处理。
通过使用 Canal,应用程序可以实现对数据库变更的监听,并将变更的数据实时同步到其他系统,比如消息队列、缓存系统等。
先记一下缓存雪崩的问题,
缓存雪崩是指在我们的系统中,大量的缓存数据在同一时间内失效,导致大量的请求直接打到数据库上,从而引发数据库压力过大甚至宕机。
Canal 可以帮助实现数据库和缓存的实时同步,减少缓存失效对数据库的冲击。但是,要彻底解决缓存雪崩问题,还需要结合其他策略,例如设置不同的缓存过期时间、使用熔断限流机制、引入分布式锁等。
下面开搞Canal,现在大部分用的springboot写项目,这里记录的用springboot集成的canal依赖,
通用的那个依赖包试了一下,没配置的太麻烦了,用法也不一样,日了小狗,所以还是用集成包,少整点配置
学的时候网上csdn上发布教程的人纯属nt。一大堆用通用包,然后使用的代码又是springboot下的,tm的找半天原因为什么找不到那个实现类,就是tm的瞎jb写教程
这里前提:
你的springboot已经引入了mysql数据库依赖,我这里用的持久层是mybatisPlus。这部分就不记录了
1.安装
1.1装Canal
下载地址:alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 (github.com)
我安装的是1.1.4版本,安装好解压 运行start脚本启动一下就行
1.2 依赖
<dependency>
<groupId>top.javatool</groupId>
<artifactId>canal-spring-boot-starter</artifactId>
<version>1.2.1-RELEASE</version>
</dependency>
1.3 写下配置
application.yml里面,加上cancal的配置,
我只填写这两个,因为很多配置是默认的,安装好后canal我没动任何配置,所以如果单独自己修改了canal的某个配置,那么这里就要自己去加上修改的东西
canal:
server: 127.0.0.1:11111 # Canal服务器地址和端口
destination: example # Canal目的地名称
记得连接mysql数据库的其它配置自己加上去,我这里就不写了
1.4 mysql数据库给权限和开启binlog功能
数据库开启一下binlog功能:
找到你的mysql配置文件,加上这个配置:
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
就是我划的这三行,在[mysqld]下面直接加上就行,然后重启一下mysql
然后还有下一步,
mysql数据库还要给一下权限才可以让canal接入进来,读取mysql数据库的binlog,才可以捕获到增删改事件。
mysql中直接执行一下:
create user canal@'%' IDENTIFIED by 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%' ;
FLUSH PRIVILEGES;
解释:
-
CREATE USER canal@'%' IDENTIFIED BY 'canal';
:创建一个新用户canal
,并设置密码为canal
。'%'
表示该用户可以从任何主机连接到MySQL服务器。 -
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SUPER ON *.* TO 'canal'@'%';
:给canal
用户授予一系列权限,包括:SELECT
:允许用户查询数据库。REPLICATION SLAVE
:允许用户请求从服务器的binlog。REPLICATION CLIENT
:允许用户查询二进制日志文件的位置。SUPER
:允许用户执行一些超级用户级别的操作,例如获取当前binlog文件的名称和位置。
-
FLUSH PRIVILEGES;
:刷新权限,使更改立即生效。
2.实战
2.1 创建实体类
和数据库的 user用户表字段 对应上
写好表名
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name ="user")
public class User {
@TableId(type = IdType.AUTO)
@Id
private Integer id;
private String name;
private String password;
}
2.2 创建监控器
@Component
@CanalTable(value = "user")
public class UserCanalListener implements EntryHandler<User> {
@Override
public void insert(User user) {
System.out.println("新增了一条数据:" + user);
}
@Override
public void update(User before, User after) {
System.out.println("数据修改前:" + before);
System.out.println("数据修改后:" + after);
}
@Override
public void delete(User user) {
// EntryHandler.super.delete(user);
System.out.println("删除用户user = " + user);
}
}
实现 EntryHandler<实体类>即可,
这里的insert 对应的就是插入数据的操作,我这里 触发插入的操作后,就把 插入的数据打印出来
后面的 update就是更新,delete就是删除。
手动在数据库改一下数据,canal就会监控到事件,执行你的代码,可以触发后修改redis数据库,进行数据和缓存的同步。 也可以自己写其他逻辑,同步其它数据库
2.3 效果
首先,现在的数据库有两条记录,我演示把张三的 password 字段改一下 ,改成8888888看一下
触发修改事件后:
数据改变后,触发了我们写的监控事件。打印出了改变前后的数据。
还可以打印出CanalModel信息
CanalModel model = CanalContext.getModel();
System.out.println(model);
控制台输出如下:
CanalModel{id=9, database='print_demo', table='user', executeTime=1711877623000, createTime=null}
这里可以看到 触发事件的 数据库 和表 是哪个。
3.总结
ok。没总结,很简单,这样就结束了。