Canal解决Redis与mysql缓存一致性问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 Tair(兼容Redis),内存型 2GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
简介: Canal解决Redis与mysql缓存一致性问题

1 缓存一致性

Redis缓存与Mysql数据库的一致性问题解决:https://blog.csdn.net/ZGL_cyy/article/details/112065489


用户每次抢完红包,要查看自己抢红包记录,此时需要查询数据库表 money_log ,如果每次都查询 money_log 就会占用大量数据库资源。此时我们应该将数据存储到缓存中,每次查询直接从缓存获取即可。

但现在面临的问题是如果用户抢到了不同的红包,缓存没法及时更新,因此我们需要实现抢红包数据库数据和Redis缓存中的数据同步。


2 缓存一致性解决方案

159e7de273054b42a41187718ce0825d.png

用户每次操作数据库的时候,使用Canal监听数据库指定表的增量变化,在Java程序中消费Canal监听到的增量变化,并在Java程序中实现对Redis缓存或者Nginx缓存的更新。


用户查询的时候,先通过Lua查询Nginx的缓存,如果Nginx缓存没有数据,则查询Redis缓存,Redis缓存如果也没有数据,可以去数据库查询。


3 Canal介绍

基础知识:


java利用canal监听数据库

https://blog.csdn.net/ZGL_cyy/article/details/116563680


大数据同步工具Canal

https://blog.csdn.net/ZGL_cyy/article/details/114799026


Canal主要用途是基于 MySQL 数据库增量日志解析,并能提供增量数据订阅和消费,应用场景十分丰富。

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

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

文档地址:https://github.com/alibaba/canal/wiki/Docker-QuickStart


56b5bc154ed5482e9d83b1132936557c.png


3.1 Canal应用场景

1.电商场景下商品实时更新同步到至Elasticsearch、solr等搜索引擎;

2.价格、库存发生变更实时同步到redis;

3.数据库异地备份、数据同步;

4.代替使用轮询数据库方式来监控数据库变更,有效改善轮询耗费数据库资源。


3.2 MySQL主从复制原理

MySQL master 将数据变更写入二进制日志( binary log , 其中记录叫做二进制日志事件 binary log events ,

可以通过 show binlog events 进行查看) 2. MySQL slave 将 master 的 binary log events 拷贝到它的中继日

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

3.3 Canal工作原理

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

master 收到 dump 请求,开始推送 binary log 给 slave (即 canal ) 3.canal 解析 binary log 对象(原始为 byte

流)


2c0184eed3a047c1bfa60914fc98c12c.png


3.4 Canal配置

1)开启MySQL的bin-log

开启MySQL的binlog日志功能:

cd /etc/mysql/mysql.conf.d
在mysqld.cnf最下面添加如下配置
# 开启 binlog
log-bin=/var/lib/mysql/mysql-bin
# 选择 ROW 模式
binlog-format=ROW
# 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
server-id=12345

2)Canal安装

这里采用容器安装

docker run -p 11111:11111 --name canal -d docker.io/canal/canal-server

配置CanalServer


修改 /home/admin/canal-server/conf/canal.properties ,将它的id属性修改成和mysql数据库中server-id不同的

值,如下图:


修改 /home/admin/canal-server/conf/example/instance.properties ,配置要监听的数据库服务地址和监听数

据变化的数据库以及表,修改如下:

ca7d38b924b54cb6b9869c24f5b9eb4e.png

907b2868624b41e189ee1d93aae19a60.png

指定监听数据库表的配置如下 canal.instance.filter.regex :


mysql 数据解析关注的表,Perl正则表达式.

多个正则之间以逗号(,)分隔,转义符需要双斜杠(\)

常见例子:


  1. 所有表:.* or .\…
  2. canal schema下所有表: canal\…*
  3. canal下的以canal打头的表:canal\.canal.*
  4. canal schema下的一张表:canal.test1
  5. 多个规则组合使用:canal\…*,mysql.test1,mysql.test2 (逗号分隔)

注意:此过滤条件只针对row模式的数据有效(ps. mixed/statement因为不解析sql,所以无法准确提取tableName进行

过滤)

重启canal:

docker restart canal

不要忘了MySQL创建账号并授权:

create user canal@'%' IDENTIFIED by 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

5 同步更新Redis缓存

修改 com.oldlu.service.impl.MoneyLogServiceImpl ,添加方法 list(String username) ,代码如下:

17671650e3f4407d8f783550e51221df.png

创建类 com.oldlu.canal.MoneyLogSync ,实现消费Canal中监听到的增量数据,代码如下:

@CanalTable(value = "money_log")
@Component
public class MoneyLogSync implements EntryHandler<MoneyLog> {
@Autowired
private MoneyLogService moneyLogService;
@Autowired
private RedisTemplate redisTemplate;
/***
* 数据增加变更
* @param moneyLog
*/
@Override
public void insert(MoneyLog moneyLog) {
//查询用户的抢红包列表
List<MoneyLog> moneyLogs = moneyLogService.list(moneyLog.getUsername());
//将数据存入到Redis
redisTemplate.boundHashOps("UserMoneyLog").put(moneyLog.getUsername(),moneyLogs);
}
}

application.yml中配置Canal的地址:

#Canal配置
canal:
server: 192.168.211.141:11111
destination: example

关于微服务中如何消费Canal监听到的数据,参考参考地址: https://github.com/NormanGyllenhaal/canal-client

我们可以测试实现抢单,抢单后,数据会自动同步到Redis缓存中。


6a60593442204cbebc1be79a7d4133b2.png

目录
相关文章
|
24天前
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
167 85
|
21天前
|
缓存 监控 NoSQL
Redis经典问题:缓存穿透
本文详细探讨了分布式系统和缓存应用中的经典问题——缓存穿透。缓存穿透是指用户请求的数据在缓存和数据库中都不存在,导致大量请求直接落到数据库上,可能引发数据库崩溃或性能下降。文章介绍了几种有效的解决方案,包括接口层增加校验、缓存空值、使用布隆过滤器、优化数据库查询以及加强监控报警机制。通过这些方法,可以有效缓解缓存穿透对系统的影响,提升系统的稳定性和性能。
|
2月前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
|
2月前
|
存储 缓存 NoSQL
【赵渝强老师】基于Redis的旁路缓存架构
本文介绍了引入缓存后的系统架构,通过缓存可以提升访问性能、降低网络拥堵、减轻服务负载和增强可扩展性。文中提供了相关图片和视频讲解,并讨论了数据库读写分离、分库分表等方法来减轻数据库压力。同时,文章也指出了缓存可能带来的复杂度增加、成本提高和数据一致性问题。
【赵渝强老师】基于Redis的旁路缓存架构
|
2月前
|
SQL 缓存 关系型数据库
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴因未能系统梳理MySQL缓存机制而在美团面试中失利。为此,尼恩对MySQL的缓存机制进行了系统化梳理,包括一级缓存(InnoDB缓存)和二级缓存(查询缓存)。同时,他还将这些知识点整理进《尼恩Java面试宝典PDF》V175版本,帮助大家提升技术水平,顺利通过面试。更多技术资料请关注公号【技术自由圈】。
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
|
2月前
|
缓存 NoSQL Redis
Redis 缓存使用的实践
《Redis缓存最佳实践指南》涵盖缓存更新策略、缓存击穿防护、大key处理和性能优化。包括Cache Aside Pattern、Write Through、分布式锁、大key拆分和批量操作等技术,帮助你在项目中高效使用Redis缓存。
386 22
|
2月前
|
缓存 NoSQL PHP
Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出
本文深入探讨了Redis作为PHP缓存解决方案的优势、实现方式及注意事项。Redis凭借其高性能、丰富的数据结构、数据持久化和分布式支持等特点,在提升应用响应速度和处理能力方面表现突出。文章还介绍了Redis在页面缓存、数据缓存和会话缓存等应用场景中的使用,并强调了缓存数据一致性、过期时间设置、容量控制和安全问题的重要性。
47 5
|
2月前
|
缓存 NoSQL 中间件
redis高并发缓存中间件总结!
本文档详细介绍了高并发缓存中间件Redis的原理、高级操作及其在电商架构中的应用。通过阿里云的角度,分析了Redis与架构的关系,并展示了无Redis和使用Redis缓存的架构图。文档还涵盖了Redis的基本特性、应用场景、安装部署步骤、配置文件详解、启动和关闭方法、systemctl管理脚本的生成以及日志警告处理等内容。适合初学者和有一定经验的技术人员参考学习。
280 7
|
2月前
|
存储 缓存 监控
利用 Redis 缓存特性避免缓存穿透的策略与方法
【10月更文挑战第23天】通过以上对利用 Redis 缓存特性避免缓存穿透的详细阐述,我们对这一策略有了更深入的理解。在实际应用中,我们需要根据具体情况灵活运用这些方法,并结合其他技术手段,共同保障系统的稳定和高效运行。同时,要不断关注 Redis 缓存特性的发展和变化,及时调整策略,以应对不断出现的新挑战。
79 10
|
2月前
|
缓存 NoSQL 关系型数据库
mysql和缓存一致性问题
本文介绍了五种常见的MySQL与Redis数据同步方法:1. 双写一致性,2. 延迟双删策略,3. 订阅发布模式(使用消息队列),4. 基于事件的缓存更新,5. 缓存预热。每种方法的实现步骤、优缺点均有详细说明。
137 3