Redis - 缓存的双写一致性

概念: 当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

那为什么会有不一致的情况呢?

如果不追求一致性,正常有两种做法

  1. 先修改数据库 后删除旧的缓存
  2. 先删除旧的缓存 再修改数据库

我们以先删除旧的缓存,再修改数据库为例:

  1. 当 线程1 要对数据库做更新操作的时候,先将Redis中旧的缓存删掉
  2. 不巧此时线程之间发生切换,线程2读取缓存,因为被线程1删掉了,所以缓存未命中
  3. 线程2就直接查询数据库,并重建缓存(将此时的数据库数据写回Redis)
  4. 接着又切换回线程1,线程1将数据库中的数据修改为新的值

此时就出现了数据库和缓存中的数据不一致的问题

因此我们不能只进行一次缓存删除操作,要使用双删的方法

  1. 比如先删除旧的缓存,修改完数据库后,再删除一次缓存

但是单纯双删不能解决问题,比如

  1. 当 线程1 要对数据库做更新操作的时候,先将Redis中旧的缓存删掉
  2. 不巧此时线程之间发生切换,线程2读取缓存,因为被线程1删掉了,所以缓存未命中
  3. 线程2就直接查询数据库,获取当前数据库的值,但未重建缓存
  4. 接着又切换回线程1,线程1将数据库中的数据修改为新的值,并再次删除缓存
  5. 此时又切换为线程2,线程2将当时读取到的值写回Redis,又造成了数据不一致

因此我们可以采取 延迟双删策略

还是上面那个例子:

  1. 当 线程1 要对数据库做更新操作的时候,先将Redis中旧的缓存删掉
  2. 不巧此时线程之间发生切换,线程2读取缓存,因为被线程1删掉了,所以缓存未命中
  3. 线程2就直接查询数据库,获取当前数据库的值,但未重建缓存
  4. 接着又切换回线程1,线程1将数据库中的数据修改为新的值,但不马上删除缓存,而是等待一段时间
  5. 切换为线程2,线程2将当时读取到的值写回Redis
  6. 最后切换回线程1,线程1再将Redis中的数据删除

可以看到 延迟双删策略 确实能解决数据一致性的问题,但延迟的时间很难确定,短了怕上面的例子中,第6步先于第5步执行,长了怕在第5步和第6步之间的数据不一致状态持续时间太长

因此我们需要另外的解决方案

针对双写一致性有两种场景: 一致性要求高允许短暂不一致

这两种场景的解决方案不同

一致性要求高

可以使用如下的分布式锁方案

在这里插入图片描述

但是我们可以看到该方案让并发变为了串行,极大降低了性能

因此我们可以使用读写锁

读锁 readLock: 加了读锁之后,其他线程还能继续加读锁和读数据,但是不能写,也不能加写锁

写锁 writeLock:写锁是排他锁,加锁之后,其他线程阻塞,不能进行读写操作

Redission 以及实现了读写锁

代码实例

读锁

在这里插入图片描述

写锁

在这里插入图片描述

其中 redissonClient.getReadWriteLock()中传入的值必须是一样的

允许短暂不一致

实际上的开发过程中,这种场景才是主流

这种场景的解决方法很多,比较常用的方法是 异步通知保持数据的最终一致性

流程图如下:

在这里插入图片描述

修改数据库时,需要发送修改记录给MQ,缓存服务需要监听MQ,根据MQ中的修改记录更新缓存

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【玩转pandas系列】数据清洗(文末送书福利)

文章目录 一、重复值检测二、元素替换1️⃣ 元素替换replace2️⃣ 数据映射map 三、修改索引1️⃣ 修改索引名rename2️⃣ 设置索引和重置索引 四、数据处理1️⃣ apply与applymap2️⃣ transform 五、异常值处理六、抽样聚合函数1️⃣ 抽样2️⃣ 数学函数 七、分组聚合&#x…

数字世界未来十年面貌如何?

随着科技的不断发展和创新,数字世界将在未来十年迎来一系列革命性的变化和进步。以下是数字世界未来十年面貌的一些预测: 人工智能全面普及:人工智能将逐渐渗透到我们生活的方方面面。从智能家居到智能交通,从个性化医疗到智能零售…

用python编写一个小程序,如何用python编写软件

大家好,给大家分享一下用python编写一个小程序,很多人还不知道这一点。下面详细解释一下。现在让我们来看看! 1、python可以写手机应用程序吗? 我想有人曲解意思了,人家说用python开发渣蔽一个手机app,不是…

零基础C#编写上位机如何入门?

学习C#基础语法和.NET框架,掌握基本编程概念和语法,例如数据类型、类、对象、继承、多态、异常处理等。学习WinForm窗体应用程序开发技术,掌握窗体应用程序的设计和开发,例如控件的使用、事件驱动编程、窗体的布局与设计等。学习数…

《向量数据库指南》——Milvus Cloud 2.3 和 2.4 版本的重要变化

Milvus Cloud2.3 和 2.4 版本的重要变化。 首先是 Milvus Cloud2.3 将支持 Json 数据类型,在此基础上亦会支持 Schemaless。此前,用户在使用 Milvus Cloud的过程中会先定一个静态 Schema,此时,如果在实际业务层面如果多了几个 feature 或者 Metadata,就意味着数据需要重新…

什么是架构 架构图

如何成为一名架构师,架构师成长之路_golang架构师成长之路_个人渣记录仅为自己搜索用的博客-CSDN博客 如何画架构图_个人渣记录仅为自己搜索用的博客-CSDN博客 如何画好一张架构图?(内含知识图谱) - 知乎 什么是架构?要表达的到…

代码随想录算法训练营第二十八天 | Leetcode随机抽题检测

Leetcode随机抽题检测--使用题库:Leetcode热题100 1 两数之和未看解答自己编写的青春版重点题解的代码日后再次复习重新写 49 字母异位词分组未看解答自己编写的青春版重点题解的代码日后再次复习重新写 128 最长连续序列未看解答自己编写的青春版重点关于 left 和 …

黑客技术(网络安全)学习笔记

一、网络安全基础知识 1.计算机基础知识 了解了计算机的硬件、软件、操作系统和网络结构等基础知识,可以帮助您更好地理解网络安全的概念和技术。 2.网络基础知识 了解了网络的结构、协议、服务和安全问题,可以帮助您更好地解决网络安全的原理和技术…

Qt 2. QSerialPortInfo显示串口信息

在ex2.pro 添加&#xff1a; QT serialport//main.cpp #include "ex2.h" #include <QtSerialPort/QtSerialPort> #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Ex2 w;w.show();QList<QSerialPortInfo>…

出海拍|疯了!ChatGPT 大规模封号,有钱还不赚?

时代洪流裹挟命运流转&#xff0c;世事变迁暗藏跨境沉浮。 几个月前&#xff0c;OpenAI的创始人之一马斯克曾在社交媒体平台上称赞ChatGPT &#xff1a;“Its a new world. Goodbye homework!”而他所说的ChatGPT 引领着许多AI工具&#xff0c;随后便开始如雨后春笋般出现在我…

刷题学算法

刷题学算法 数据结构 一、数组 1. 数组创建&#xff1a; // 方式1&#xff1a;先创建&#xff0c;再逐个存储元素 String[] cityArray1 new String[5]; cityArray1[0] "北京"; cityArray1[1] "上海"; cityArray1[2] "广州"; cityArray1[3…

【RabbitMQ(day4)】SpringBoot整合RabbitMQ与MQ应用场景说明

一、SpringBoot 中使用 RabbitMQ 导入对应的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency>配置配置文件 spring:application:name: rabbitmq-springbo…

linux备份与还原系统(类似window上ghost备份还原)

一、摘要 在linux上进行了几年的开发工作 &#xff08;qt ros&#xff09; 突然发现&#xff0c;现在有公司硬件、笔记本台式机一台占一个系统&#xff0c;导致硬件太浪费&#xff0c;又不能用虚拟机&#xff08;有时候要链接硬件必须物理机&#xff09;怎么办&#xff1f; 二…

【C++】开源:Boost库常用组件配置使用

&#x1f60f;★,:.☆(&#xffe3;▽&#xffe3;)/$:.★ &#x1f60f; 这篇文章主要介绍Boost库常用组件配置使用。 无专精则不能成&#xff0c;无涉猎则不能通。——梁启超 欢迎来到我的博客&#xff0c;一起学习&#xff0c;共同进步。 喜欢的朋友可以关注一下&#xff0c…

CSS font-family 等宽字体

CSS font-family 等宽字体 font-family: "Lucida Console", Consolas, "Courier New", Courier, monospace; font-family: Courier New, Courier, Lucida Console, Consolas, monospace; font-family: Courier, Lucida Console, Consolas, Courier New,…

多赛道出海案例,亚马逊云科技为企业提供全新解决方案实现高速增长

数字化浪潮之下&#xff0c;中国企业的全球化步伐明显提速。从“借帆出海”到“生而全球化”&#xff0c;中国企业实现了从低端制造出口&#xff0c;向技术创新和品牌先导的升级。为助力中国企业业务高效出海&#xff0c;亚马逊云科技于2023年6月9日在深圳大中华喜来登酒店举办…

推荐50个超实用的 Chrome 扩展,建议收藏!

今天来分享 50 个超实用的 Chrome 浏览器扩展&#xff01; JSON Viewer Pro JSON Viewer Pro 用于可视化JSON文件。其核心功能包括&#xff1a; 支持将JSON数据进行格式化&#xff0c;并使用属性或者图表进行展示&#xff1b;使用面包屑深入遍历 JSON 属性&#xff1b;在输入…

【Python机器学习】实验04(1) 多分类(基于逻辑回归)实践

文章目录 多分类以及机器学习实践如何对多个类别进行分类1.1 数据的预处理1.2 训练数据的准备1.3 定义假设函数&#xff0c;代价函数&#xff0c;梯度下降算法&#xff08;从实验3复制过来&#xff09;1.4 调用梯度下降算法来学习三个分类模型的参数1.5 利用模型进行预测1.6 评…

直播预告 | 开源运维工具使用现状以及可持续产品的思考

运维平台自上世纪90年代开始进入中国市场&#xff0c;曾形成以传统四大外企&#xff1a;IBM、BMC、CA、HP为代表的头部厂商&#xff0c;还有一众从网管起家的国内厂商。2010年前后&#xff0c;出现了以Zabbix、Nagios、Cacti为代表的开源工具&#xff0c;后来又陆续出现了Prome…

k8s概念-deployment

deployment用于部署无状态应用 Deployment集成了上线部署、滚动升级、创建副本、回滚等功能 Deployment里包含并使用了ReplicaSet Replicaset 通过改变Pod副本数量实现Pod的扩容和缩容 参考文档 https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/ …
最新文章