百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

不用背八股文!一文搞懂redis缓存击穿、穿透、雪崩!

nanshan 2024-12-12 14:06 10 浏览 0 评论

缓存的击穿、穿透和雪崩,对于这三大缓存的问题,有很多人背过了八股文式的解决方案,面试也能答上一二,却少有人能把思路给理清的。

这三个问题产生的前提是高并发,但是一旦发生,会导致大量的请求积压到数据库层,并发量很大,甚至会引起数据库宕机或是故障,造成严重的生产事故。下面我将一一分析,保证让你看得明白透彻!

系统架构

在解释缓存问题之前,我们先来复习一下系统架构,知道问题出在哪,才能找到解决之道。

一个大的spring cloud微服务集群,从客户端发送请求开始,会先经过F5、Nginx等流量分发层,然后到spring cloud gateway的服务网关,最后才到我们的后端服务service。而service会先从缓存查找数据,没有再去数据库找。

redis作为缓存,在整个系统体系中,就是将很多的请求扛住,过滤掉,从而使得最后的数据库的压力就会很小。很显然只有在大流量、高并发的时候,redis没能扛住访问请求,才会导致击穿、穿透、雪崩的出现。

缓存击穿

缓存击穿是指,针对某个访问非常频繁的热点数据的请求,无法在缓存中获取,紧接着,访问该数据的大量请求,一下子都发送到了后端数据库,导致了数据库压力激增,直接影响数据库无法处理其他请求。

说白了,就是某一个热点数据,缓存中某一时刻失效了,因而大量并发请求打到数据库上,就像redis被打了一个窟窿,被击穿了一样,此时,该数据redis中没有,数据库中才有。


解决方案

网上查到的方法都是说设置 key 永不过期,也就是不设置过期时间,但是数据总是会变的,那这时候该如何处理呢?思考以下几种方式,看是否有缺陷。

  1. 在更新数据库时,同时更新key
  2. 后台起一个定时任务,每隔一段时间,在 key 快要失效的时候,提前将 key 刷新为最新数据
  3. 每次获取 key 都检查,key 还有多久过期,如果快过期,则更新这个 key

这些方案其问题在于,更新操作不是原子性的,无法保证数据库和redis缓存数据的一致性,所以在实际的生产环境中,是无法胜任的。

这时候就可以考虑使用redis分布式锁,通过分布式锁来实现数据库和redis的数据同步。

具体操作如下:当service访问缓存key为空时,先加锁,加锁成功后往mysql写数据,接着更新缓存,然后释放锁;加锁失败,说明有其他service已经加上了锁,需等待或循环尝试查缓存和加锁。

但是加锁也有讲究,不是简单的setnx命令。如果加分布式锁的service在加锁成功后突然挂掉,那锁就无法释放,所以加分布式锁的同时,还要原子性的给锁设置超时时间。

其实redis的set命令就能够满足我们当前的需求:

Bash
SET key value [EX seconds] [PX milliseconds] [NX|XX]

其中,key是要存储的键名,value是要存储的值。EX和PX参数可选,用于设置键的过期时间,单位分别为秒和毫秒。NX和XX参数也可选,用于控制键的创建行为,NX表示只在键不存在时创建,XX表示只在键已存在时执行操作。

那这就万无一失了吗,答案肯定是否定的,分布式锁key的时候设置多长我们并不清楚,太短可能线程还没执行完业务逻辑,太长响应又过慢。为解决这一问题,需要引入redisson工具,利用redisson的看门狗机制来控制key的超时时间。

【文章福利】:免费领取C/C++ 开发学习资料包、技术视频/项目代码,1000道大厂面试题,内容包括(C++组件,网络编程,数据库,中间件,后端开发,音视频开发,Qt开发,游戏开发,Linux内核等进阶学习资料和最佳学习路线),免費分享,有需要的可以加君羊领取哦!~学习交流君羊927239107点击加入领取资料

缓存穿透

缓存穿透是指要访问的数据既不在 Redis 缓存中,也不在数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。此时,应用也无法从数据库中读取数据再写入缓存,来服务后续请求,这样一来,缓存也就成了“摆设”。

解决方案

第一种方案是,缓存空值或缺省值。一旦发生缓存穿透,可以针对查询的数据,在 Redis 中缓存一个特殊的缺省值。应用发送的后续请求再进行查询时,就可以直接从 Redis 中读取该值,返回给业务使用,避免了把大量请求发送给数据库处理,保持了数据库的正常运行。

不过,数据库中不存在的数据有很多,像依据前端入参作为key的缓存,如果每个都设置缺省值就会造成空间上的浪费,这时候就得考虑方案二。

第二种方案是,使用布隆过滤器快速判断数据是否存在,避免从数据库中查询数据是否存在,减轻数据库压力。布隆过滤器的底层数据结构是bitmap,即用一个比特位来表示一个key,花费 1 个字节的空间,就能存储 8 个 key。

一个比特位只能是0或1,无法表示更多信息,一个key经过一次哈希算法算的哈希值(即要落在第几个比特位)就有可能和其他key存在冲突。为解决冲突,就需要多次哈希,相应的一个key就需要多个比特位来存储。

这样,只要对应出我们的需求,去调整 bitmap 的大小,以及哈希函数的个数,就可以大大过滤出存在的key,降低缓存穿透的概率。

如果数据频繁增删改,是不太适合用布隆过滤器的。因为一个数据变更之后,布隆过滤器无法删除 key,因此,只能重新创建一个布隆过滤器,再加载一遍所有的数据,创建出新的bitmap。那么,解决的话,可以使用带删除功能的布谷鸟布隆过滤器,来满足动态变化的需求。

最后一种方案是,在请求入口的前端进行请求检测。缓存穿透的一个原因是有大量的恶意请求访问不存在的数据,所以,一个有效的应对方案是在请求入口前端,对业务系统接收到的请求进行合法性检测,把恶意的请求(例如请求参数不合理、请求参数是非法值、请求字段不存在)直接过滤掉,不让它们访问后端缓存和数据库。这样一来,也就不会出现缓存穿透问题了。

缓存雪崩

缓存雪崩,指的是大面积的 key 同时过期,导致大量并发打到我们的数据库。不像击穿,只是因为 1 个 key 的过期。那就算一个 key 失效,也会对数据库造成很大的影响,那么可以把雪崩的所有 key 拆成一个一个 key 来看,也就是雪崩可以拆分成一个一个缓存击穿的集合。

其实在真实场景中,雪崩才是一个更容易发生的一个问题,它不像击穿那么极端,一个 key 就成千上万的并发,直接把数据库打垮了;而是,可能就一个 key 几十几百的并发,然后大量的 key 一过期,然后就使得好多并发同时叠加起来,累积到上千上万个,把数据库打崩了。

解决方案

首先,我们可以避免给大量的数据设置相同的过期时间。如果业务层的确要求有些数据同时失效,可以在用 EXPIRE 命令给每个数据设置过期时间时,给这些数据的过期时间增加一个较小的随机数(例如,随机增加 1~3 分钟),这样一来,不同数据的过期时间有所差别,但差别又不会太大,既避免了大量数据同时过期,同时也保证了这些数据基本在相近的时间失效,仍然能满足业务需求。

除了微调过期时间,我们还可以通过服务降级,来应对缓存雪崩。

一旦发生了缓存雪崩,数据库的每秒请求数突然增加到每秒 1 万个,此时,我们就可以启动请求限流机制,在请求入口前端只允许每秒进入系统的请求数为 1000 个,再多的请求就会在入口前端被直接拒绝服务。所以,使用了请求限流,就可以避免大量并发请求压力传递到数据库层。

不过,要考虑一种情况,就是,如果你的业务对时点性要求高,必须每天的指定时间,去更新我们的数据,比如游戏排行每日零点更新。在某一个固定的时间,由于业务要求,必须使得数据刷新,并且不允许出现旧数据,让缓存全部失效。像这样的业务应该怎么办?

既然 redis 无法分散过期时间,那就在业务层下功夫。时间一到,redis 数据全部失效,大量并发前来查询,在 service 服务层查询时,设置一个短暂的随机延迟时间,这样,少量的请求,先查询,就会读数据库,然后存入 redis;其他请求,由于随机时间稍稍慢了点,就可以去 redis 读出数据。

相当于是从业务层把时间分散。客户可能会多那么几十毫秒的延迟,不过影响微乎其微,是可以接受的。

总结

从问题成因来看,缓存雪崩和击穿主要是因为数据不在缓存中了,而缓存穿透则是因为数据既不在缓存中,也不在数据库中。所以,缓存雪崩或击穿时,一旦数据库中的数据被再次写入到缓存后,应用又可以在缓存中快速访问数据了,数据库的压力也会相应地降低下来,而缓存穿透发生时,Redis 缓存和数据库会同时持续承受请求压力。

对于缓存的击穿、雪崩、穿透,看似很平常简单的问题,重要的,不是死记硬背八股文式的答案,而是能够从系统和架构的角度,去理清设计原由和解决思路。

相关推荐

三种自建KMS激活系统自动激活windows方法

第一种:在windows服务器上搭建主要针对vol版本(win7、win10、win20xx、win2012等等)平台:我自己搭建的windows虚拟机,windows2016的操作系统软件:...

重装系统被收98元?避开Windows付费陷阱的实用指南

重装系统被收98元?避开Windows付费陷阱的实用指南有网友反映,在重装Windows系统后,屏幕突然弹出“激活系统需支付98元服务费”的提示,疑惑自己是不是遭遇了付费陷阱。事实上,微软官方的Wi...

Windows Server2012远程桌面服务配置和授权激活

安装:注意:安装完毕之后需手动重启一下计算机配置终端服务管理工具---远程桌面服务---RD授权诊断程序,查看当前服务器有没有授权授权:运行—>gpedit.msc->计算机配置---管理...

新书速览|Windows Server 2022 系统与网站配置实战

讲述桌面体验、ServerCore/NanoServer,容器与云系统的配置1本书内容《WindowsServer2022系统与网站配置实战》秉持作者一贯理论兼具实践的写作风格,以新版的Wi...

Windows激活全攻略:KMS神钥与专业工具的完美结合!

对于许多Windows用户来说,系统的激活是一个必经的过程。虽然Windows操作系统在未经激活的状态下也可以使用一段时间,但长期来看,未激活的系统会限制某些功能并频繁提示用户激活。以下是两种流行的激...

微软Win9全新激活技术曝光(微软系统激活有什么用)

2014-07-0905:46:00作者:徐日俄罗斯Wzor日前披露了更多关于Windows9的最新消息,据悉,Windows9将会在今年秋季亮相,其宣传口号是“想要开始按钮和开始菜单?如你所...

快速激活Windows 10/11:CMD命令详细教程

#记录我的2024#激活Windows操作系统是确保系统功能和安全更新正常运行的重要步骤。本文将为您分享如何使用命令提示符(CMD)在Windows10和Windows11上进行激活的详细步骤。...

Wndows 2019 RDS应用发布部署(rds的安装和应用程序的发布)

安装前的准备1、需要提供服务器作为应用中心,应用中心的推荐配置如下表所示。规格建议1-10人11-20人21-50人51-100人100+人CPU4核8核16核内存8GB16GB32GB64GB系统盘...

解决 Windows 系统激活难题(如何解决windows激活问题)

今天,一位朋友给我说,他手头有三台电脑,均同时弹出系统未激活的提示。他对此毫无头绪,便急忙将电脑上出现的激活提示信息一股脑发给了我。我看到其中一台显示的是“Windows10企业版LTSC尚...

自建KMS激活服务器(自建kms激活服务器的风险)

自建KMS激活服务器Win10和office安装后,都需要激活才可以使用,一般可以输入购买的MAK激活码进行在线激活,也可以通过KMS激活,网上也有很多激活工具,但这些工具一般都含有病毒或木马程序,容...

30秒免费激活windows和office亲测有效!

“第三方工具有病毒?”“KMS服务器激活总失效?”今天给大家分享一个开源激活工具——MicrosoftActivationScripts(MAS),无需密钥、不装软件,30秒永久激活Window...

「操作系统」Windows 10 LTSC 2019 企业版C大集成更新版

Windows10LTSC企业版CHIANNET集成更新优化整合多镜像版,CHIANNET,是USBOS超级PE维护盘工具箱作者,长久以来一直默默的更新着,USBOSPE软件,电脑城装机及...

一文看懂Windows激活:自查方法+授权类型科普(Win7/Win10通用)

一、如何判断Windows是否永久激活?无论是Win7还是Win10,均可通过以下方法快速验证:命令提示符法(通用):按下Win+R,输入slmgr.vbs/xpr并按回车键运行即可查看是否...

部分Windows Server 2019/2022用户反馈无法运行微软Teams应用

IT之家7月2日消息,科技媒体borncity今天(7月2日)发布博文,报道称在多个WindowsServer版本上,MicrosoftTeams应用近期出现了运行故障。用...

这种Windows激活方式已有20年...(windows现在激活)

2006年微软正式发布WindowsVista,随之而来引入了一项新的激活机制「OEM激活」,这项机制在Vista和Win7上最为流行。其实WindowsServer自2008开始至2025版本一...

取消回复欢迎 发表评论: