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;

解释:

  1. CREATE USER canal@'%' IDENTIFIED BY 'canal';:创建一个新用户canal,并设置密码为canal'%'表示该用户可以从任何主机连接到MySQL服务器。

  2. GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT, SUPER ON *.* TO 'canal'@'%';:给canal用户授予一系列权限,包括:

    • SELECT:允许用户查询数据库。
    • REPLICATION SLAVE:允许用户请求从服务器的binlog。
    • REPLICATION CLIENT:允许用户查询二进制日志文件的位置。
    • SUPER:允许用户执行一些超级用户级别的操作,例如获取当前binlog文件的名称和位置。
  3. 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。没总结,很简单,这样就结束了。

 

posted @ 2024-03-31 17:02  Hello霖  阅读(105)  评论(0编辑  收藏  举报