图解Redis:如何保证先更新数据库再删除缓存同时执行成功

如何保障 MySQL 和 Redis 的数据一致性? 对于这种方案,看看就行,反正我是不会用,太Low了,风险也不可控。 阅读详情

前情回顾

上回程序员阿旺为了提升数据访问的性能,引入 Redis 作为 MySQL 缓存层,但是这件事情并不是那么简单,因为还要考虑 Redis 和 MySQL 双写一致性的问题。

阿旺经过一番周折,最终选用了「先更新数据库,再删缓存」的策略,原因是这个策略即使在并发读写时,也能最大程度保证数据一致性。

聪明的阿旺还搞了个兜底的方案,就是给缓存加上了过期时间。

本以为就这样不会再出现数据一致性的问题,结果将功能上线后,老板还是收到用户的投诉「说自己明明更新了数据,但是数据要过一段时间才生效」,客户接受不了。

老板转告给了阿旺,阿旺得知又有 Bug 就更慌了,立马就登录服务器去排查问题,查看日志后得知了原因。

「先更新数据库, 再删除缓存」其实是两个操作,这次客户投诉的问题就在于,在删除缓存(第二个操作)的时候失败了,导致缓存中的数据是旧值,而数据库是最新值。

好在之前给缓存加上了过期时间,所以才会出现客户说得过一段时间才更新生效的现象,假设如果没有这个过期时间的兜底,那后续的请求读到的就会一直是缓存中的旧数据,这样问题就更大了。

所以新的问题来了,如何保证「先更新数据库 ,再删除缓存」这两个操作能执行成功?

阿旺分析出问题后,慌慌张张地向老板汇报了问题。

老板知道事情后,又给了阿旺几天来解决这个问题,画饼的事情这次没有再提了。

  • 阿旺会用什么方式来解决这个问题呢?
  • 老板画的饼事情,能否兑现给阿旺呢?

如何保证两个操作都能执行成功?

这次用户的投诉是因为在删除缓存(第二个操作)的时候失败了,导致缓存还是旧值,而数据库是最新值,造成数据库和缓存数据不一致的问题,会对敏感业务造成影响。

举个例子,来说明下。

应用要把数据 X 的值从 1 更新为 2,先成功更新了数据库,然后在 Redis 缓存中删除 X 的缓存,但是这个操作却失败了,这个时候数据库中 X 的新值为 2,Redis 中的 X 的缓存值为 1,出现了数据库和缓存数据不一致的问题。

那么,后续有访问数据 X 的请求,会先在 Redis 中查询,因为缓存并没有 诶删除,所以会缓存命中,但是读到的却是旧值 1。

其实不管是先操作数据库,还是先操作缓存,只要第二个操作失败都会出现数据一致的问题。

问题原因知道了,该怎么解决呢?有两种方法:

  • 重试机制。
  • 订阅 MySQL binlog,再操作缓存。

先来说第一种。

重试机制

我们可以引入消息队列,将第二个操作(删除缓存)要操作的数据加入到消息队列,由消费者来操作数据。

  • 如果应用删除缓存失败,可以从消息队列中重新读取数据,然后再次删除缓存,这个就是重试机制。当然,如果重试超过的一定次数,还是没有成功,我们就需要向业务层发送报错信息了。
  • 如果删除缓存成功,就要把数据从消息队列中移除,避免重复操作,否则就继续重试。

举个例子,来说明重试机制的过程。

订阅 MySQL binlog,再操作缓存

「先更新数据库,再删缓存」的策略的第一步是更新数据库,那么更新数据库成功,就会产生一条变更日志,记录在 binlog 里。

于是我们就可以通过订阅 binlog 日志,拿到具体要操作的数据,然后再执行缓存删除,阿里巴巴开源的 Canal 中间件就是基于这个实现的。

Canal 模拟 MySQL 主从复制的交互协议,把自己伪装成一个 MySQL 的从节点,向 MySQL 主节点发送 dump 请求,MySQL 收到请求后,就会开始推送 Binlog 给 Canal,Canal 解析 Binlog 字节流之后,转换为便于读取的结构化数据,供下游程序订阅使用。

下图是 Canal 的工作原理:

所以,如果要想保证「先更新数据库,再删缓存」策略第二个操作能执行成功,我们可以使用「消息队列来重试缓存的删除」,或者「订阅 MySQL binlog 再操作缓存」,这两种方法有一个共同的特点,都是采用异步操作缓存。

老板发饼啦

阿旺由于对消息队列比较熟悉,所以他决定采用「消息队列来重试缓存的删除」的方案,来解决这次的用户问题。

经过几天几夜的操作,服务器搞定了,立马向老板汇报工作。

老板让阿旺再观察些时间,如果没问题,到中秋节就商量“饼”的事情。

时间过得很快,中秋佳节到了,这期间一直都没有用户反馈数据不一致的问题。

老板见这次阿旺表现很好,没有再出现任何差错,服务器的访问性能也上来了,于是给阿旺发了这个超级大的月饼,你看这个饼又大又圆,就像你的代码又长又多。

阿旺看到这个月饼,哭笑不得,没想到这就是老板画的饼,是真的很大饼。。。。

以上故事纯属虚拟,如有巧合,以你为准。

更多技术交流,关注公众号

 

分布式技术原理与实战45讲--40 第35讲:经典问题:先更新数据库,还是先更新缓存? 这一课时我们探讨了缓存和数据库一致性的问题,包括业务开发中如何通过控制更新缓存和数据库的时序,来尽量避免最终一致性问题。在专栏的第 1 课时就讨论过分布式系统的 CAP 理论,经过这么长时间的学习,你是否对 CAP 理论中的不可能三角有了更深的理解呢?在你负责的项目中,是如何应用缓存,又如何保证缓存和数据库数据一致性的呢,欢迎留言进行分享。 阅读详情

相关推荐

58一面:Redis数据更新,是先更新数据库还是先更新缓存?

光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性光给面试题不给答案不是我的风格。这里面的面试题也只是凤毛麟角,还有答案的话会极大的增加文章的篇幅,减少文章的可读性。

2401_84413490的博客 1162

先更新数据库还是先清缓存的问题

先清缓存还是先清数据库问题

weixin_59230567的博客 3157

Mysql/Redis缓存一致性

如何保证MySQL和Redis的缓存一致。从理论到实战。总结6种来感受一下。

qq_64948664的博客 1723

redis进阶:mysql,redis双写一致性,数据库更新后再删除缓存就够了吗?

最近线上的一个状态修改功能出现了问题,一开始是运营找了过来,运营告知某条数据的状态已经开启了的,但是实际使用起来还是没有生效,于是拿到这个问题后,首先就去数据库查了这条数据,发现确实如他所说,状态数据是已经更改过的。但是为什么没有生效呢?于是再次查看了获取数据的方法,发现是优先获取的缓存,于是查询缓存里的数据,发现了问题所在,缓存里并没有将这条数据的状态更改过来,也就是缓存数据不一致问题。继续追查状态修改的方法,发现采用的更新方式是先更新数据库,然后删除缓存。

55555的博客 3924

图解数据库和Redis缓存的一致性(延时双删与延时后删的区别及重要性)

图解数据库和Redis缓存的一致性 问题来源 使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库: 读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。 不管是先写MySQL数据库,再删除Redis缓存,再更新缓存;还是先删除缓存,再写库,再更新缓存。都有可能出现数据不一致的情况。举一个例子: 1.如果删除了缓存Redis,还没有来得及写库MySQL,另一个线程就来读取,发现缓

Charte的博客 2808

MySQL数据库和Redis缓存一致性的更新策略

延时双删可以解决上面的问题,只要sleep的时间大于线程2读取数据再写入缓存的时间就可以了,也就是线程1的二次清缓存操作要在线程2写入缓存之后,这样才能保证Redis缓存中的数据是最新的。

学Java,找哪吒 7862

Redis更新缓存的正确姿势(先更新DB,再删除缓存)

1.更新缓存的三种模式 引入缓存势必会导致数据的一致性问题(因为分别存放到缓存以及DB),那么在数据更新时,缓存和DB都得更新,并且更新时序的不同会导致不同的结果。关于数据更新目前业界已经沉淀了Cache Aside Pattern,Read/Write through,Write Behind Caching等三种方式。 Cache Aside :同时更新缓存和数据库; Read/Write Through:先更新缓存,缓存负责同步更新数据库; ...

Java后端技术栈 7574

从宁德新能源面试官视角,拆解Halcon/OpenCV图像处理工程师的硬核技能树(附避坑指南)

本文从宁德新能源面试官视角出发,详细拆解Halcon/OpenCV图像处理工程师的核心技能树,涵盖硬件选型、算法实现和系统工程思维三大能力维度。文章提供工业视觉工程师面试的实战避坑指南,包括硬件配置要点、算法优化技巧及职业发展路径,助力求职者系统提升图像处理专业技能。

weixin_28732953的博客 129

图解Redis缓存篇

因为 Redis 是内存数据库,我们可以将数据库的数据缓存在 Redis 里,相当于数据缓存在内存,内存的读写速度比硬盘快好几个数量级,这样大大提高了系统性能。引入了缓存层,就会有缓存异常的三个问题,分别是缓存雪崩、缓存击穿、缓存穿透。先更新数据库后更新缓存先更新缓存,后更新数据库所以,无论是「先更新数据库,再更新缓存」,还是「先更新缓存,再更新数据库」,这两个方案都存在并发问题,当两个请求并发更新到同一条数据的时候,可能会出现缓存和数据库中的数据不一致的现象。

小小博客 1011

自动驾驶仿真:Carsim、NI和VTD联合仿真课题二

文章目录前言一、设备配置1、硬件需求2、网络配置二、Carsim工程配置1、创建工程2、创建数据库3、参数配置三、VTD工程配置1、创建工程四、Veristand工程配置1、创建工程五、运行程序 前言 上篇文章《Carsim、NI和VTD联合仿真课题一》简单地介绍了三者之间的联合框架,以及NI与VTD之间简单的组包与拆包指导。这篇文章将要讲述的是如何将三个软件联合起来,如何设置软件参数,用最简单的方法把仿真车开起来。 一、设备配置 1、硬件需求 注:真正的做智能驾驶仿真项目,至少需要两台电脑,一台实时机

zataji的博客 1万+

避坑指南:CentOS7.9安装Python3.8.16后yum报错的快速修复方法

本文详细解析了在CentOS7.9系统安装Python3.8.16后导致yum报错的原因,并提供了快速修复方法。通过修改yum配置文件指向Python2解释器,以及使用alternatives工具管理多版本Python,有效解决兼容性问题。同时推荐使用虚拟环境隔离开发环境,避免影响系统稳定性。

weixin_26908317的博客 495

趣说 | 数据库和缓存如何保证一致性?

数据库和缓存如何保证一致性? 一天,老板说「最近公司的用户越来越多了,但是服务器的访问速度越来越差的,阿旺帮我优化下,做好了给你画个饼!」。 程序员阿旺听到老板口中的「画饼」后就非常期待,没有任何犹豫就接下了老板给的这个任务。 阿旺登陆到了服务器,经过一番排查后,确认服务器的性能瓶颈是在数据库。 这好办,给服务器加上 Redis,让其作为数据库的缓存。 这样,在客户端请求数据时,如果能在缓存中命中数据,那就查询缓存,不用在去查询数据库,从而减轻数据库的压力,提高服务器的性能。 先更新数据库,还是先更新缓存

小林coding 3987

双目相机立体匹配算法概述(含Python代码)

立体匹配任务是计算机视觉中的一个重要问题,旨在从一对具有相同场景的图像中估计每个像素的视差(disparity)。本文对现有的传统算法和深度学习算法进行了综述,以便于各位选择合适的立体匹配算法用于深度估计或三维建模。

m0_59257547的博客 8291

如何保证数据库与 Redis 缓存的一致性?

方案是否一致并发安全实现复杂度备注先更新 DB 再删缓存❌ 否否简单常见误区,不能用先删缓存再更新 DB⚠️ 部分一定程度简单可配合延迟双删使用延迟双删✅ 最终一致较高简单推荐大部分场景分布式锁✅ 强一致是中等对性能影响较大MQ 异步清缓存✅ 最终一致是中等解耦,适合高并发Binlog + Canal 回刷缓存✅ 强一致是高推荐核心数据系统使用Redis 缓存作为提升系统性能的利器,也带来了“一致性”的挑战。

Harry的博客 910

测试用例经典练习之微信发红包测试用例

微信发红包测试用例

ZCYaiCLX3344的博客 1万+

2026年华为od机试真题题库

OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)OD统一考试(E卷)

面试高手的博客 19万+

图解Redis:一套方案轻松搞定数据库与缓存数据不一致问题

但是这个方案前面我们也分析过,在两个更新请求并发执行的时候,会出现数据不一致的问题,因为更新数据库和更新缓存这两个操作是独立的,而我们又没有对操作做任何并发控制,那么当两个线程并发更新它们的话,就会因为写入顺序的不同造成数据的不一致。「先更新数据库,再删除缓存」的方案虽然保证了数据库与缓存的数据一致性,但是每次更新数据的时候,缓存的数据都会被删除,这样会对缓存的命中率带来影响。「先更新数据库, 再删除缓存」其实是两个操作,前面的所有分析都是建立在这两个操作都能同时执行成功,而这次客户投诉的问题就在于,

2401_83916355的博客 914

RT-Thread littefs控制GD32F4xx片内Flash

GD32F4xx RT-Thread下使用littefs 控制片内flash 调试记录

madao1234的博客 995

先删Redis缓存再更新数据库?先更新数据库再删Redis缓存!数据一致性

先删Redis缓存再更新数据库?先更新数据库再删Redis缓存!数据一致性

weixin_48334973的博客 700

推荐系统[一]:超详细知识介绍,一份完整的入门指南,解答推荐系统相关算法流程、衡量指标和应用,以及如何使用jieba分词库进行相似推荐,业界广告推荐技术最新进展

推荐算法其实本质上是一种信息处理逻辑,当获取了用户与内容的信息之后,按照一定的逻辑处理信息后,产生推荐结果。热度排行榜就是最简单的一种推荐方法,它依赖的逻辑就是当一个内容被大多数用户喜欢,那大概率其他用户也会喜欢。但是基于粗放的推荐往往会不够精确,想要挖掘用户个性化的,小众化的兴趣,需要制定复杂的规则运算逻辑,并由机器完成。召回:当用户以及内容量比较大的时候,往往先通过召回策略,将百万量级的内容先缩小到百量级。

丨汀、的博客 7591

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Redis 缓存:应对缓存雪崩、缓存击穿和缓存穿透

缓存雪崩是指在某一时刻,大量缓存数据同时过期或 Redis 服务宕机,导致所有请求直接打到数据库,造成数据库瞬间压力激增,甚至崩溃。缓存击穿是指某个被高频访问的热点 Key在过期的瞬间,大量并发请求同时无法命中缓存,全部涌向数据库,造成瞬时压力激增。⚠️ 与雪崩不同:雪崩是“大面积失效”,击穿是“单个热点失效”。缓存穿透是指查询一个数据库中也不存在的数据,导致缓存无法命中,每次请求都必须查询数据库。恶意攻击者可能利用此漏洞,构造大量不存在的 Key,持续请求,压垮数据库。

Landcc的博客 1681

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

总算搞懂了!困扰我的Redis缓存与DB一致性问题

使用缓存的时候,我们需要关注Redis与DB数据的一致性。如果Redis缓存与DB数据不一致,就可能导致用户一直只能获取到数据错误的缓存,严重影响用户体验。那如何让Redis与DB数据一致性呢?

weixin_71690375的博客 698

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

总算搞明白了!难倒大片人的Redis缓存与DB一致性问题

使用缓存的时候,我们需要关注Redis与DB数据的一致性。如果Redis缓存与DB数据不一致,就可能导致用户一直只能获取到数据错误的缓存,严重影响用户体验。那如何让Redis与DB数据一致性呢?

wdj_yyds的博客 337

深入浅出缓存(Redis)

深入浅出缓存(Redis)

CERTAINTY的博客 1754
上一篇: 阿里三面惨虐,spring,jvm,mybatis,并发编程等一窍不通
下一篇: 给面试官上一课:HTTPS是先进行TCP三次握手,再进行TLS四次握手
跟着我学Java
博客等级 码龄6年 660粉丝 1341原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值