Redis缓存一致性问题

news2024/10/7 4:36:10

目录

1、背景

2、缓存读写模式

2.1、Cache-Aside Pattern(旁路缓存模式)

2.2、Read-Through/Write-Through(读写穿透模式)

2.3、Write Behind Pattern(异步缓存写入)

3、数据不一致的几种场景

3.1、先删缓存,再更新数据库

3.2、先更新数据库,再删缓存

4、解决方案

4.1、延时双删

4.2、消息队列

4.3、进阶版消息队列(基于订阅binlog的同步机制)

4.4、数据对比

5、为什么是删除,而不是更新缓存?


1、背景

        高并发场景下,如果让所有的请求都直接访问数据库,大概率数据库是扛不住这么大的并发压力的。所以,通常情况下,我们会使用Redis做一个缓冲操作,请求来时,先去查询Redis缓存,如果能在缓存中查到数据,则直接返回;如果查不到,再去查询数据库。

        读场景下,Redis和数据库在数据一致性层面没什么问题,但是,在涉及到数据更新操作时:数据库和缓存更新,就会存在数据一致性问题。

2、缓存读写模式

2.1、Cache-Aside Pattern(旁路缓存模式)

        适用于读多写少的场景。使用该模式的系统对缓存失效具有一定的弹性,即使缓存集群宕机,系统仍然可以通过访问数据库获取到数据,只不过这种情况下可能会降低响应时间,严重的话会搞崩数据库。

读流程:

  • 读的时候,先读缓存,缓存命中的话,直接返回数据
  • 缓存没有命中的话,就去读数据库,从数据库取出数据,放入缓存后,同时返回响应。

写流程:

  • 更新的时候,先更新数据库,然后再删除缓存

2.2、Read-Through/Write-Through(读写穿透模式)

        Cache-Aside模式下,业务系统需要同时维护缓存和数据库,以此来保证缓存和数据库的数据一致性。

        Read/Write Through模式下,提供一个缓存服务,由缓存服务维护缓存与数据库的数据一致性,业务系统只需要与缓存服务进行读写即可,不必再关心缓存与数据库的一致性问题。

读流程:

  • 业务系统发读请求给缓存服务
  • 缓存服务:从缓存读取数据,读到直接返回
  • 缓存服务:如果读取不到的话,从数据库加载,写入缓存后,再返回响应。

写流程:

  • 业务系统发写请求给缓存服务
  • 缓存服务:更新数据库
  • 缓存服务:更新缓存

2.3、Write Behind Pattern(异步缓存写入)

        类比Read-Through/Write-Through模式,都是由一个缓存服务负责缓存和数据库的读写。不同点在于,Write Behind Pattern模式执行写操作时,只更新缓存,不直接更新数据库,通过异步批量的方式写入数据库。

        数据存储的写性能很高,但数据的一致性变差,极端场景下可能会丢失数据。

        适用于变更频率很高,但对一致性要求不太高的业务场景。

3、数据不一致的几种场景

        由于数据库和缓存(比如Redis)是两个组件,所以不可能在一个事务中处理,那么数据的更新就会存在一个先后问题。

3.1、先删缓存,再更新数据库

原始数据:缓存中有key = value1,数据库有key = value1。

  1. 线程1删除缓存key成功
  2. 线程2读取数据,缓存key已被删除,从数据库读取key=value1,并写入缓存key=value1
  3. 线程1更新数据库key = value2

此时,缓存中key=value1,数据库中key=value2,数据不一致。

3.2、先更新数据库,再删缓存

原始数据:缓存中有key = value1,数据库有key = value1。

  1. 线程1更新数据库key = value2;
  2. 线程1删除缓存key,删除失败。

此时,缓存中key=value1,数据库中key=value2,数据不一致。

4、解决方案

4.1、延时双删

        在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。

  • 删除缓存
  • 更新数据库
  • 休眠500毫秒(休眠时间由读业务逻辑耗时决定,确保读请求结束后,写请求可以删除读请求造成的缓存脏数据)
  • 再次删除缓存
  • 读请求更新缓存时,给缓存设置超时时间

4.2、消息队列

        先更新数据库,成功后往消息队列发消息,消费到消息后再删除缓存,借助消息队列的重试机制来实现,达到最终一致性的效果。

        但是,引入消息队列后,就需要考虑消息中间件的维护问题、消息丢失问题、消息延迟等问题。

4.3、进阶版消息队列(基于订阅binlog的同步机制)

        MySQL binlog增量订阅消费+消息队列+增量数据更新到redis。

  • 读Redis:热数据基本都在Redis
  • 写MySQL:增删改都是操作MySQL
  • 更新Redis数据:MySQ的数据操作binlog,来更新到Redis

        使用canal订阅mysql的binlog,一旦MySQL中产生了新的读写、更新、删除操作,通过消息队列,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。

4.4、数据对比

        通过数据对比模块,发现差异,差异报警,自动修复,定时将mysql数据同步到redis中。

5、为什么是删除,而不是更新缓存?

如果是更新的话,那就是先更新数据库,再更新缓存

举个例子:如果数据库1小时内更新了1000次,那么缓存也要更新1000次,但是这个缓存可能在1小时内只被读取了1次,那么这1000次的更新有必要吗?

反过来,如果是删除的话,就算数据库更新了1000次,那么也只是做了1次缓存删除,只有当缓存真正被读取的时候才去数据库加载。

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

部分内容截取自网络,如有侵权,联系作者删除。

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

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

相关文章

豆瓣评分9.1!据说入门Python的人都读过

前言 你是否正在寻找一本适合初学者入门Python的书籍呢? 如果是,那你来对地方了,以我个人经验,开始学习一门新的编程语言是相当困难和耗时的,这也是我今天要和大家分享这本书的原因,不卖关子了&#xff0…

算法竞赛入门【码蹄集进阶塔335题】(MT2051-2075)

算法竞赛入门【码蹄集进阶塔335题】(MT2051-2075) 文章目录算法竞赛入门【码蹄集进阶塔335题】(MT2051-2075)前言为什么突然想学算法了?为什么选择码蹄集作为刷题软件?目录1. MT2051 矩阵01变2. MT2052 矩形3. MT2053 切蛋糕4. MT…

面试怕问到缓存穿透?看这篇就够了

面试怕问到缓存穿透?看这篇就够了! 缓存穿透 缓存穿透指的是请求的数据在数据库和缓存中都不存在,这样缓存永远都不会生效,这些请求就会直接打到数据库中。 就比方说,你去查询一个商户,带着id为负数的参数…

艾美捷SAM甲基转移酶活性分析试剂盒使用前准备方案

关键生物分子和蛋白质的甲基化在许多生物系统,包括信号转导、生物合成、蛋白质修复、基因沉默和染色质调节。S-腺苷甲硫氨酸(SAM)依赖性甲基转移酶使用SAM ATP后最常用的酶辅因子。SAM,也称为AdoMet作为修饰蛋白质和DNA所需的甲基…

通俗理解决策树

目录前言决策树的结构决策树的构建信息增益(ID3算法)信息增益率(C4.5算法)基尼指数(CART算法)熵VS基尼指数剪枝优缺点及适用场景参考文献前言 从这一期开始,我们准备介绍一系列经典机器学习算法…

Linux:虚拟机配置免密登录和文件同步分发

记录下,以后照抄就好了 文章目录ssh免密登录SCP安全拷贝rsync同步修改xsync集群分发ssh免密登录 免密登录原理 生成公钥和私钥 ssh-keygen -t rsa后连敲三个回车 将公钥拷贝到要免密登录的目标机器上 遇到yes/no的都输入yes ssh-copy-id m1 ssh-copy-id m2 ssh-co…

JAVA毕业设计——基于Springboot+vue的校园二手交易和交流论坛系统(源代码+数据库)

github代码地址 https://github.com/ynwynw/stuSecond-public 毕业设计所有选题地址 https://github.com/ynwynw/allProject 基于Springbootvue的校园二手交易和交流论坛系统(源代码数据库)039 一、系统介绍 这是集校园二手交易、校园交流论坛、校园表白墙为一体的项目。分为…

Java基于微信小程序的新冠疫苗预约小程序 springboot+vue+elementUI

项目介绍 基于小程序的疫苗预约系统是计算机技术与疫苗管理相结合的产物,通过疫苗预约系统实现了对疫苗的高效管理。随着计算机技术的不断提高,计算机已经深入到社会生活的各个角落.而采用人工疫苗预约的方法,不仅效率低,易出错,手…

Python基础(十四):公共操作的讲解

文章目录 公共操作的讲解 一、运算符 1、+ 2、* 3、in或not in 二、公

面了个腾讯35k出来的,他让我见识到什么叫“精通MySQL调优”

始末 MySQL调优对于很多程序员而言,都是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰。在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多的查询优化工作实际上就是遵循一些原则让MySQL的优化器能…

CN_@TCP可靠机制@差错控制@流量控制@拥塞控制

文章目录CN_TCP可靠机制差错控制流量控制拥塞控制TCP的可靠性机制序号确认窗口大小和累计确认🎈Window scaling重传超时冗余ACK(冗余确认快速重传)差错控制🎈TCP流量控制🎈接收窗口:拥塞窗口:发送窗口例例例1例2例3例例…

【Node.js】实现微信小程序订阅消息推送功能

实战项目名称:实现微信小程序订阅消息通知 文章目录一、实战步骤1. 登录微信小程序管理端,添加订阅消息模板2. 定义好需要发送的消息3.获取小程序的access_token4. 发起请求,向用户推送消息4. 小程序端添加接收订阅消息的按钮二、完整源代码三…

基于Python+Django的学生作业提交批改管理系统

在各学校的教学过程中,学生的作业管理是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及,“基于网络的学习模式”正悄无声息的改变着传统的教室学习模式,“基于网络的教学平台”的研究和设计也成为教育技术领域的热点课题。采用…

ZeroTier实现内网穿透详细教程,其实5分钟就可以搞定

想看更详细的视频教程,推荐到哔哩哔哩上看:强大的内网穿透工具ZeroTier,随时随地远程访问家中NAS和其它设备!没有公网IP也不怕_哔哩哔哩_bilibili 相信很多人都有远程连接家中设备的需求,如远程连接家中的NAS、Window…

基于JAVA的书舍管理系统的设计与实现

摘 要 随着图书馆规模的不断扩大,人流数量的急剧增加,有关图书馆的各种信息量也在不断成倍增长。面对庞大的信息量,就需要有书舍管理系统来提高图书馆工作的效率。通过这样的系统,我们可以做到信息的规范管理和快速查询&#xff…

python 算法加密

加密代码片段样例 文件名:iter_n.py import timedef iter_from_n(n):list_n []for index,value in enumerate(range(n)):list_n.append([index,value])return list_nif __name__"__main__":t1 time.time()iter_from_n(100000)t2 time.time()print (&…

精彩预告 | 美创科技与您线上相约第十三届中国数据库技术大会

12月14日~16日,由IT168联合旗下ITPUB、ChinaUnix两大技术社区主办的第13届中国数据库技术大会(DTCC2022)将在线上隆重召开。 作为一家在数据库技术领域深研探索十余年的厂商,美创科技持续专注推动数据库技术的发展与实践。此次大会…

在平台上便捷使用LS-DYNA的方式

LS-DYNA 由Livermore Software Technology Corporation (LSTC) 开发,是一种多用途的显式和隐式有限元和多物理场程序,用于分析结构的非线性响应;其全自动接触分析和广泛的材料模型使全球用户能够解决复杂的现实问题。 这里要注意的是&#x…

【Vue】Vue2基本使用

文章目录一、模板语法1、插值语法写法介绍2、指令语法写法介绍模板语法示例二、数据绑定介绍数据绑定示例效果三、初始化Vue时,data属性与el属性的两种写法el的两种写法data的两种写法演示案例四、MVVM模型介绍五、数据代理JS数据代理案例演示Vue数据代理介绍原理六…

汽车自动驾驶的L0-L5是什么意思?

一、问题 汽车L0、L1、L2、L3、L4、L5自动驾驶都是什么意思呢? 近年来「自动驾驶」对我们来说不再陌生,很多人虽然早有所闻,但是真不懂自动驾驶的L0、L1、L2、L3、L4、L5是什么意思,都有哪些功能,今天就来为大家科普一…