redis缓存一致性以及解决方案

news2025/7/12 9:26:45

一致性问题:
首先要到redis里面读取缓存,如果没有缓存,那么就到mysql里面去取数据,并且将其放置在缓存中

关于解决缓存一致性的问题,不难想到主要有两种解决方案,双更模式和删除模式
**

双更模式:

**
双更模式,顾名思义就是更新两次,一次更新redis,一次更新mysql
不难想到,如果我们先更新redis,再更新mysql的话,是不是就可以保证每次缓存中的数据都是最新的了?
但是这样做是有问题的,比如如果我们更新mysql的时候失败了怎么办?更新数据库可能会失败,发生了回滚。所以,最后“缓存里的数据”和“数据库的数据”就不一样了,也就是出现了数据一致性问题。

那如果先更新mysql,再更新redis呢?
由于数据库和 Redis 的操作,并不是原子的,它们的执行时长也不是可控制的。当两个请求的时序发生了错乱,就会发生缓存不一致的情况。

综上,双更模式下,数据不一致的概率较大,一般不建议使用双更模式。


删除模式


删除模式即更新数据时,删除redis,查询时重新从数据库中加载数据。
先删除缓存
请求A删除了某个 key 的值,这时候有另外一个请求B 到来,那么它就会击穿到数据库,读取到旧的值。无论操作A更新数据库的操作持续多长时间,都会产生不一致的情况。
后删除缓存
后删除缓存不会出现上述问题。一般情况下这种方式可以解决大部分问题,也是最常用的解决方案。
但是在高并发的情况下,仍有可能出现不一致的情况。场景如下:
有一系列的高并发操作,一直执行着更新、删除的动作。某个时刻,它更新数据库的值为 1,然后删除了缓存。
正在这时,有两个请求发生了:

一个是读操作,读到的当然是数据库的旧值 1,我们记作操作 A;
同时,另外一个请求发起了更新操作,把数据库记录更新为 2,我们记作操作 B。
一般情况下,读取操作都是比写入操作快的,但我们要考虑两种极端情况:

一种是这个读取操作 A,发生在更新操作 B 的尾部;
一种是操作 A 的这个 Redis 的操作时长,耗费了非常多的时间。比如,这个节点正好发生了 STW。(条件比较苛刻)
那么很容易地,读操作 A 的结束时间就超过了操作 B 删除的动作。

实际上,你也无法控制它们的执行顺序。只要发生这种情况,大概率数据库和Redis的值会不一致。


解决方案:


延迟双删
延时双删的方案的思路是,为了避免更新数据库的时候,其他线程从缓存中读取不到数据,就在更新完数据库之后,再sleep一段时间,然后再次删除缓存。
sleep的时间要对业务读写缓存的时间做出评估,sleep时间大于读写缓存的时间即可。
流程如下:
线程1删除缓存,然后去更新数据库
线程2来读缓存,发现缓存已经被删除,所以直接从数据库中读取,这时候由于线程1还没有更新完成,所以读到的是旧值,然后把旧值写入缓存
线程1,根据估算的时间,sleep,由于sleep的时间大于线程2读数据+写缓存的时间,所以缓存被再次删除
如果还有其他线程来读取缓存的话,就会再次从数据库中读取到最新值
设置较小的缓存时间
俗称闪电缓存,即把缓存的失效时间设置非常短,比如 5秒。一旦失效,就会再次去数据库读取最新数据到缓存,即数据不一致只会在短时间内不一致。但这种方式,在非常高的并发下,同一时间对某个 key 的请求击穿到 DB,产生缓存击穿问题
消息队列
先更新数据库,成功后往消息队列发消息,消费到消息后再删除缓存,借助消息队列的重试机制来实现,达到最终一致性的效果。
在这里插入图片描述

进阶版消息队列
一般大公司本身都会有监听binlog消息的消息队列存在,主要是为了做一些核对的工作。
这样,我们可以借助监听binlog的消息队列来做删除缓存的操作。这样做的好处是,不用你自己引入,侵入到你的业务代码中,中间件帮你做了解耦,同时,中间件的这个东西本身就保证了高可用。
当然,这样消息延迟的问题依然存在,但是相比单纯引入消息队列的做法更好一点。
在这里插入图片描述


支持事务的缓存


Apache geode是不错的Redis的替换,支持事务,缓存不一致好多时候是Redis不支持事务引起,Geode的商业版本GemFire就是当年支持12306的神器,稳定性,性能都很好
在这里插入图片描述
链接如下
https://github.com/apache/geode

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/38468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JVM】native关键字的使用

native关键字的使用一、JVM体系结构二、native是什么?三、native能干什么?四、native怎么使用?五、native总结在研读**《深入理解Java虚拟机》这本书时,看到 Java 虚拟机运行时数据区中有关本地方法栈**(Native Method…

鲜花在线销售平台的设计与实现/鲜花商城/网上花店管理系统

摘 要 为了解决客户便捷地在网上购物,本文设计和开发了一个鲜花在线销售平台。本系统是基于web架构设计,SSM框架,javascript技术的前台页面设计与实现,使用Mysql数据库管理,综合采用java模式来完成系统的相关功能。主…

【GlobalMapper精品教程】028:栅格计算器的使用方法总结

文章目录 一、栅格计算器简介二、栅格计算器应用举例1. 归一化植被指数NDVI2. 归一化水体指数NDWI3. 归一化建筑指数NDBI一、栅格计算器简介 GlobalMapper中也提供了栅格计算器工具,可以方便的进行栅格计算、波段计算、指数计算等,使用方法有点儿像Envi软件。 用户可以使用系…

世界杯来了,让 Towhee 带你多语言「以文搜球」!

四年一度的世界杯已正式拉开战幕,各小组比赛正如火如荼地进行中。在这样一场球迷的盛宴中,不如让 Towhee 带你「以文搜球」,一览绿茵场上足球战将们的风采吧~ 「以文搜球」是跨模态图文检索的一部分,如今最热门的跨模…

Leetcode刷题Day5休息 Day6----------哈希表

Leetcode刷题Day5休息 & Day6----------哈希表 1. 哈希表理论基础 数组、Set、Map 如果数据量小------------数组 如果数据量大------------Set 如果有Key、value------------Map 文章讲解:https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86…

【雷达检测】基于复杂环境下的雷达目标检测技术(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜…

数据之道读书笔记-06面向“自助消费”的数据服务建设

数据之道读书笔记-06面向“自助消费”的数据服务建设 数据底座建设的目标是更好地支撑数据消费,在完成数据的汇聚、整合、联接之后,还需要在供应侧确保用户更便捷、更安全地获取数据。一方面业务人员希望尽可能快速地获取各种所需的数据,另一…

基于双目相机拍摄图像的深度信息提取和目标测距matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB程序 1.算法描述 双目相机一般由左眼和右眼两个水平放置的相机组成。当然也可以做成上下两个目,但我们见到的主流双目都是做成左右的。在左右双目的相机中,我们可以把两个相机都看作针…

大数据毕设选题 - 深度学习图像超分辨率重建(opencv python cnn)

文章目录0 前言1 什么是图像超分辨率重建2 应用场景3 实现方法4 SRResNet算法原理5 SRCNN设计思路6 代码实现6.1 代码结构组织6.2 train_srresnet6.3 训练效果7 最后0 前言 🔥 Hi,大家好,这里是丹成学长的毕设系列文章! &#x…

读写分离和主从复制

这是只有一个数据库的情形,此时增删改查都是针对这个数据库而言 存在两个问题:所有压力都是由一台数据库承担,数据库压力很大 而且,一旦这个数据库发生故障,数据丢失,拿数据就全都没了 现在有两个数据库&…

总结使人进步,4句真章的理解和实践

在“总结使人进步,遵循事物的客观发展规律;祸福相依,知行合一”这篇文章里,首次全面提出了4句真章。 这么多年,最有感触的4句话。 一、4句真章 1、总结使人进步 2、遵循事物的发展规律 3、祸福相依 4、知行合一 …

muduo库中实现Protbuf编码器与消息分发器

文章目录1. protobuf的type name反射机制2. Protobuf编码器2.1 protbuf传输格式2.2 message转换为Buffer2.3 Buffer转换为message2.4 onMessage和send3. 消息分发器dispatcher3.1 成员变量3.2 onProtobufMessage3.3 registerMessageCallback4. 简单RPC4.1 query.proto4.2 serve…

QT:debug日志—打不开头文件以及qDebug和Q_CLASSINFO的使用

这个是因为链接器在给定路径上搜索不到对应的头文件,而大多数的Qt相关的头文件都集中在一个include文件夹里: 我电脑上的路径是:C:\Qt\Qt5.9.7\5.9.7\msvc2017_64\include 然后我们在项目设置里: 注意,这边要加上\*&…

Linux系统配置及服务管理-06-存储管理

基本分区 磁盘简介 磁盘/硬盘/disk是一个东西,不同于内存的是容量比较大。 类型 从工作原理区分 机械 机械硬盘即是传统普通硬盘,主要由:盘片,磁头,盘片转轴及控制电机,磁头控制器,数据转换…

钢材缺陷检测系统-ui界面

钢材缺陷检测系统-ui界面 之前写过这个博客: 工业缺陷检测项目实战(二)——基于深度学习框架yolov5的钢铁表面缺陷检测 里面介绍了使用yolov5进行训练的步骤。今天我们一起学习利用qt将缺陷检测封装为一个系统。 效果 首先看看效果: 我们运行,先可以看…

26岁月薪从7k到17K,这一切都要从那年失业讲起...

女生,目前在成都做了快4年的测试 先来说说我自己是怎么入行的以及我学到的一些经验分享,希望能帮助到更多的朋友们 我大学学的并不是计算机相关专业,学的市场营销,毕业后大部分同学都去做销售或者商务BD了,奈何自己性…

Redis复习笔记

文章目录Redis一、redis入门1.1、NoSQL的引言1.2、为什么是NoSQL1.3、NoSQL的四大分类1.3.1 键值(Key-Value)存储数据库1.3.2 列存储数据库1.3.3 文档型数据库1.3.4 图形(Graph)数据库1.4 NoSQL应用场景1.5 什么是Redis1.6 Redis特点1.7 Redis 安装二、redis数据库相关指令2.1 …

vue-swiper组件化:解决异步请求数据时swiper过早初始化问题:

最初始的swiper组件封装&#xff1a; <body><div id"box"><swiper></swiper></div><script>Vue.component("swiper", {template: <div class"swiper"><div class"swiper-wrapper">…

PC_磁盘HDD_SSD/存储介质(材料工艺)

文章目录外存磁盘存储器组成磁盘驱动器磁盘控制器盘片platter存储区域磁盘结构磁道track道距位密度扇区sector&#x1f388;/块Block&#x1f386;磁头(Head)圆柱面cylinder磁记录原理磁盘性能指标记录密度磁盘的容量非格式化容量格式化容量数据传输率磁盘转速旋转周期T例平均存…

自学网络安全?一般人我还是劝你算了吧

前言 本人纯屌丝一枚&#xff0c;在学网络安全之前对电脑的认知也就只限于上个网&#xff0c;玩个办公软件。这里不能跑题&#xff0c;我为啥说自学网络安全&#xff0c;一般人我还是劝你算了吧。因为我就是那个一般人。 基础真的很简单&#xff0c;是个人稍微认点真都能懂&a…