Canal 实战 | 第一篇:SpringBoot 整合 Canal + RabbitMQ 实现监听 MySQL 数据库同步更新 Redis 缓存

简介: Canal 实战 | 第一篇:SpringBoot 整合 Canal + RabbitMQ 实现监听 MySQL 数据库同步更新 Redis 缓存

一. Canal 简介

微信图片_20230710083040.png


canal [kə’næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费


早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。


基于日志增量订阅和消费的业务包括


数据库镜像

数据库实时备份

索引构建和实时维护(拆分异构索引、倒排索引等)

业务 cache 刷新

带业务逻辑的增量数据处理

当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x


二. Canal 工作原理

1. MySQL主备复制原理

微信图片_20230710083044.jpg


MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)

MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)

MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

2. Canal 工作原理

Canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议


MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )


Canal 解析 binary log 对象(原始为 byte 流)


三. Canal 实战

1. 需求分析

有来项目 youlai-mall 当前进度下使用Redis缓存MySQL数据库中的OAuth2客户端信息、角色权限映射关系、菜单路由,现在这样有两个很明显的问题:


在后台管理界面修改角色、菜单、权限和OAuth2客户端任何一方信息都需要让缓存失效或者更新缓存,代码耦合性高;

数据库直接修改上面相关信息,缓存无法失效或更新。

第一种情况至少有解决方案,无非就在代码层面上清缓存或者更新缓存,但是如果是直接修改数据库呢?实际工作可能经常会遇到直接修改数据库的场景,本篇通过SpringBoot 整合 Canal + RabbitMQ 实现对数据库的监听然后同步让缓存失效或者更新。当然有来项目引入 Canal 中间件刷新缓存只是个开始,接下来还会使用 Canal 同步商品表至 ElasticSearch。


2. MySQL开启 binlog 日志

MySQL 部署:https://www.cnblogs.com/haoxianrui/p/15488810.html


开启 biglog 日志


vim /etc/my.cnf

1

添加配置


[mysqld]

log-bin=mysql-bin # 开启binlog

binlog-format=ROW # 选择ROW模式

server_id=1 # 配置MySQL replaction需要定义,不和Canal的slaveId重复即可

重启MySQL ,查看配置是否生效


show variables like 'log_bin';

1

微信图片_20230710083110.png


3. RabbitMQ 队列创建

添加交换机 canal.exchange

微信图片_20230710083113.png


添加队列 canal.queue


微信图片_20230710083133.png

队列绑定交换机

微信图片_20230710083137.png

微信图片_20230710083153.png



4. Canal 配置和启动

Canal Server下载

官方文档:https://github.com/alibaba/canal/wiki

项目地址:https://github.com/alibaba/canal

下载地址:https://github.com/alibaba/canal/releases

进入下载地址,选择 canal.deployer-1.1.5.tar.gz


微信图片_20230710083205.png


将压缩包解压,我这里把最后解压出来的文件放入 有来项目 的middleware中间件文件,和之前的 nacos 和 sentinel 同一个套路。


微信图片_20230710083208.png


Canal Server配置

需要配置的东西就两项,一个是监听数据库配置,另一个是 RabbitMQ 连接配置。


改动的两个文件分别是 Canal 配置文件 canal.properties 和 实例配置文件 instance.properties


㊙️:一个 Server 可以配置多个实例监听 ,Canal 功能默认自带的有个 example 实例,本篇就用 example 实例 。如果增加实例,复制 example 文件夹内容到同级目录下,然后在 canal.properties 指定添加实例的名称。

微信图片_20230710083231.png



canal.properties


配置 Canal 服务方式为 RabbitMQ 和连接配置(🏷 只列出需要修改的地方)


# tcp, kafka, rocketMQ, rabbitMQ

canal.serverMode = rabbitMQ

##################################################

#########       RabbitMQ      #############

##################################################

rabbitmq.host = x.youlai.tech

rabbitmq.virtual.host =/

rabbitmq.exchange =canal.exchange

rabbitmq.username =guest

rabbitmq.password =guest

rabbitmq.deliveryMode =


instance.properties


监听数据库配置(🏷 只列出需要修改的地方)


# position info

canal.instance.master.address=x.youlai.tech:3306

# username/password

canal.instance.dbUsername=root

canal.instance.dbPassword=root

# mq config

canal.mq.topic=canal.routing.key



5. SpringBoot 整合 Canal + RabbitMQ

🏠 完整源码:https://gitee.com/youlaitech/youlai-mall


引入依赖

<dependency>

   <groupId>org.springframework.boot</groupId>

   <artifactId>spring-boot-starter-amqp</artifactId>

</dependency>


RabbitMQ连接配置

spring:

 rabbitmq:

   host: x.youlai.tech

   port: 5672

   username: guest

   password: guest


RabbitMQ 监听同步缓存

/**

* Canal + RabbitMQ 监听数据库数据变化

*

* @author <a href="mailto:xianrui0365@163.com">haoxr</a>

* @date 2021/11/4 23:14

*/

@Component

@Slf4j

@RequiredArgsConstructor

public class CanalListener {

   private final ISysPermissionService permissionService;

   private final ISysOauthClientService oauthClientService;

   private final ISysMenuService menuService;

   @RabbitListener(bindings = {

           @QueueBinding(

                   value = @Queue(value = "canal.queue", durable = "true"),

                   exchange = @Exchange(value = "canal.exchange"),

                   key = "canal.routing.key"

           )

   })

   public void handleDataChange(String message) {

       CanalMessage canalMessage = JSONUtil.toBean(message, CanalMessage.class);

       String tableName = canalMessage.getTable();

       log.info("Canal 监听 {} 发生变化;明细:{}", tableName, message);

       if ("sys_oauth_client".equals(tableName)) {

           log.info("======== 清除客户端信息缓存 ========");

           oauthClientService.cleanCache();

       } else if (Arrays.asList("sys_permission", "sys_role", "sys_role_permission").contains(tableName)) {

           log.info("======== 刷新角色权限缓存 ========");

           permissionService.refreshPermRolesRules();

       } else if (Arrays.asList("sys_menu", "sys_role", "sys_role_menu").contains(tableName)) {

           log.info("======== 清理菜单路由缓存 ========");

           menuService.cleanCache();

       }

   }

}


6. 实战测试

🏷 如果使用有来项目线上 RabbitMQ 测试,记得需要新建队列,否者多人消费同一队列会让你觉得 Canal 监听数据有丢失的现象。


接下来模拟测试,当直接在数据库修改菜单数据,能否让 Redis 的菜单路由缓存失效。


启动 Canal

切换到项目的 cd ./middleware/canal/deployer/bin 目录下,输入 startup 启动 Canal


微信图片_20230710083249.png


启动 youlai-admin 应用,测试效果如下,可见最后菜单路由缓存在直接在数据库修改菜单表数据时会失效,达到预期效果。

微信图片_20230710083251.gif



四. 总结

本篇通过 Canal + RabbitMQ 实现对 MySQL 数据变动监听,能够应对实际工作直接修改数据库数据后让缓存失效或者刷新的场景。有来项目引入 Canal 本篇只是个开始,因为 Canal 的应用场景太丰富了,接下来有来项目使用 Canal 同步 MySQL 数据库的商品数据至 ElasticSearch 索引库,个人感觉以后会越来越火,所以建议有必要深入了解这个 Canal 框架。


五. 联系信息

有兴趣进交流群的童鞋欢迎加群, 纯属学习交流群,无任何利益,二维码过期可加我微信备注“有来”即可,我拉你进群,另外如果有兴趣加入开源项目 youlai-mall 开发的欢迎私信我。


相关文章
|
11月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
625 158
|
10月前
|
SQL 关系型数据库 数据库
Python SQLAlchemy模块:从入门到实战的数据库操作指南
免费提供Python+PyCharm编程环境,结合SQLAlchemy ORM框架详解数据库开发。涵盖连接配置、模型定义、CRUD操作、事务控制及Alembic迁移工具,以电商订单系统为例,深入讲解高并发场景下的性能优化与最佳实践,助你高效构建数据驱动应用。
1064 7
|
11月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
人工智能 关系型数据库 OLAP
聚光灯已就位!阿里云瑶池数据库邀你征战Cursor首届实战征文大赛
阿里云AnalyticDB携手Cursor中文社区,正式发起首届实战征文大赛!我们诚邀开发者融合Cursor的智能编程能力与AnalyticDB PostgreSQL提供的Supabase服务进行项目开发,让优秀项目被专家看见、被机遇拥抱!
|
11月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1655 152
|
11月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1125 156
|
11月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(中)
使用MYSQL Report分析数据库性能
728 156
|
11月前
|
缓存 监控 关系型数据库
使用MYSQL Report分析数据库性能(上)
最终建议:当前系统是完美的读密集型负载模型,优化重点应放在减少行读取量和提高数据定位效率。通过索引优化、分区策略和内存缓存,预期可降低30%的CPU负载,同时保持100%的缓冲池命中率。建议每百万次查询后刷新统计信息以持续优化
781 161
|
10月前
|
NoSQL 算法 Redis
【Docker】(3)学习Docker中 镜像与容器数据卷、映射关系!手把手带你安装 MySql主从同步 和 Redis三主三从集群!并且进行主从切换与扩容操作,还有分析 哈希分区 等知识点!
Union文件系统(UnionFS)是一种**分层、轻量级并且高性能的文件系统**,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem) Union 文件系统是 Docker 镜像的基础。 镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
945 6
|
11月前
|
关系型数据库 MySQL 分布式数据库
阿里云PolarDB云原生数据库收费价格:MySQL和PostgreSQL详细介绍
阿里云PolarDB兼容MySQL、PostgreSQL及Oracle语法,支持集中式与分布式架构。标准版2核4G年费1116元起,企业版最高性能达4核16G,支持HTAP与多级高可用,广泛应用于金融、政务、互联网等领域,TCO成本降低50%。

推荐镜像

更多