您的当前位置:首页 >IT科技类资讯 >重磅开源:高并发下缓存穿透、击穿、雪崩问题的解决方案! 正文
时间:2025-11-05 07:09:28 来源:网络整理编辑:IT科技类资讯
大家好,我是冰河~~记得在《【高并发】Redis如何助力高并发秒杀系统?看完这篇我彻底懂了!!》一文中,我们以高并发秒杀系统中扣减库存的场景为例,说明了Redis是如何助力秒杀系统的。那么,说到Red

大家好,重磅我是开源冰河~~
记得在《【高并发】Redis如何助力高并发秒杀系统?看完这篇我彻底懂了!!高并》一文中,发下我们以高并发秒杀系统中扣减库存的缓存场景为例,说明了Redis是穿透如何助力秒杀系统的。那么,击穿决方说到Redis,雪崩往往更多的问题场景是被用作系统的缓存,说到缓存,重磅尤其是开源分布式缓存系统,在实际高并发场景下,高并稍有不慎,发下就会造成缓存穿透、缓存缓存击穿和缓存雪崩的穿透问题。
那什么是缓存穿透?什么是缓存击穿,又什么是缓存雪崩呢?它们是如何造成的?又该如何解决呢?这次,我们不仅仅是从理论上来阐述这些内容,冰河更是香港云服务器开源了生产级高并发场景下缓存穿透、击穿和雪崩问题解决方案的落地代码,让你掌握的不仅仅是理论知识,更是落地到代码的解决方案。
首先,我们来说说缓存穿透。什么是缓存穿透呢?缓存穿透问题在一定程度上与缓存命中率有关。如果我们的缓存设计的不合理,缓存的命中率非常低,那么,数据访问的绝大部分压力都会集中在后端数据库层面。
如果在请求数据时,在缓存层和数据库层都没有找到符合条件的数据,也就是说,在缓存层和数据库层都没有命中数据,那么,这种情况就叫作缓存穿透。
我们可以使用下图来表示缓存穿透的现象。

造成缓存穿透的亿华云主要原因就是:查询某个Key对应的数据,Redis缓存中没有相应的数据,则直接到数据库中查询。数据库中也不存在要查询的数据,则数据库会返回空,而Redis也不会缓存这个空结果。这就造成每次通过这样的Key去查询数据都会直接到数据库中查询,Redis不会缓存空结果。这就造成了缓存穿透的问题。
既然我们知道了造成缓存穿透的主要原因就是缓存中不存在相应的数据,直接到数据库查询,数据库返回空结果,缓存中不存储空结果。
那我们就自然而然的想到了第一种解决方案:就是把空对象缓存起来。当第一次从数据库中查询出来的结果为空时,我们就将这个空对象加载到缓存,并设置合理的过期时间,这样,就能够在一定程度上保障后端数据库的安全。网站模板
第二种解决缓存穿透问题的解决方案:就是使用布隆过滤器,布隆过滤器可以针对大数据量的、有规律的键值进行处理。一条记录是不是存在,本质上是一个Bool值,只需要使用 1bit 就可以存储。我们可以使用布隆过滤器将这种表示是、否等操作,压缩到一个数据结构中。比如,我们最熟悉的用户性别这种数据,就非常适合使用布隆过滤器来处理。
如果我们为缓存中的大部分数据设置了相同的过期时间,则到了某一时刻,缓存中的数据就会批量过期。
如果缓存中的数据在某个时刻批量过期,导致大部分用户的请求都会直接落在数据库上,这种现象就叫作缓存击穿。
我么可以使用下图来表示缓存击穿的线程。

造成缓存击穿的主要原因就是:我们为缓存中的数据设置了过期时间。如果在某个时刻从数据库获取了大量的数据,并设置了相同的过期时间,这些缓存的数据就会在同一时刻失效,造成缓存击穿问题。
对于比较热点的数据,我们可以在缓存中设置这些数据永不过期;也可以在访问数据的时候,在缓存中更新这些数据的过期时间;如果是批量入库的缓存项,我们可以为这些缓存项分配比较合理的过期时间,避免同一时刻失效。
还有一种解决方案就是:使用分布式锁,保证对于每个Key同时只有一个线程去查询后端的服务,某个线程在查询后端服务的同时,其他线程没有获得分布式锁的权限,需要进行等待。不过在高并发场景下,这种解决方案对于分布式锁的访问压力比较大。
如果缓存系统出现故障,所有的并发流量就会直接到达数据库。
如果在某一时刻缓存集中失效,或者缓存系统出现故障,所有的并发流量就会直接到达数据库。数据存储层的调用量就会暴增,用不了多长时间,数据库就会被大流量压垮,这种级联式的服务故障,就叫作缓存雪崩。
我们可以用下图来表示缓存雪崩的现象。

造成缓存雪崩的主要原因就是缓存集中失效,或者缓存服务发生故障,瞬间的大并发流量压垮了数据库。
解决缓存雪崩问题最常用的一种方案就是保证Redis的高可用,将Redis缓存部署成高可用集群(必要时候做成异地多活),可以有效的防止缓存雪崩问题的发生。
为了缓解大并发流量,我们也可以使用限流降级的方式防止缓存雪崩。例如,在缓存失效后,通过加锁或者使用队列来控制读数据库写缓存的线程数量。具体点就是设置某些Key只允许一个线程查询数据和写缓存,其他线程等待。则能够有效的缓解大并发流量对数据库打来的巨大冲击。
另外,我们也可以通过数据预热的方式将可能大量访问的数据加载到缓存,在即将发生大并发访问的时候,提前手动触发加载不同的数据到缓存中,并为数据设置不同的过期时间,让缓存失效的时间点尽量均匀,不至于在同一时刻全部失效。
冰河已经将高并发场景下解决缓存穿透、击穿、雪崩问题的通用方案落地到代码,并开源,旨在让大家从源码级别更好的掌握解决缓存穿透、击穿和雪崩问题的通用方案。
开源项目是基于Redis解决缓存击穿、穿透和雪崩问题的通用解决方案,拿来即用。支持存储对象、集合、简单数据类型等。无需提前将数据存入Redis,直接使用提供的分布式缓存接口查询数据即可,附带完善的单元测试用例,方便学习使用,另外,项目的README.md文件中附带详细的核心接口定义、使用案例和单元测试场景。
开源地址如下,如果这个开源项目对你有点帮助!
github:https://github.com/binghe001/spring-redis。gitee:https://gitee.com/binghe001/spring-redis。gitcode:https://gitcode.net/binghe001/spring-redis。电脑显示文件大小错误的原因及解决方法(解析文件大小显示错误的常见问题及应对措施)2025-11-05 06:59
讲讲文字编码的那些事2025-11-05 06:57
2018年最具就业前景的7大编程语言:Java、Python、JavaScript前三,PHP也上榜!2025-11-05 06:47
联手!Facebook,谷歌,IBM和红帽合作开放源代码许可证!2025-11-05 06:42
电脑重启系统还原的详细步骤(一步一步教你如何进行电脑重启系统还原)2025-11-05 06:36
全栈必备 你需要了解的Java编程基础2025-11-05 06:12
网站上线无忧:Web网站压力及性能测试2025-11-05 06:04
JavaScript是真正的OOP语言吗?2025-11-05 05:31
电脑安装系统教程(轻松学会如何使用电脑安装操作系统)2025-11-05 04:57
程序员老司机都要错的Python陷阱与缺陷列表2025-11-05 04:46
联想主板安装教程(详细教您如何正确安装联想主板,让您的电脑更稳定更高效)2025-11-05 06:14
都100%代码覆盖了,还会有什么问题?2025-11-05 05:53
前端开发人员需要知道的JavaScript简写技巧(高级篇)2025-11-05 05:42
陌陌基于K8s和Docker容器管理平台的架构实践2025-11-05 05:39
手机进水了怎么办?(教你快速排水的方法,让手机重获新生!)2025-11-05 05:11
如何使用Python对Instagram进行数据分析?2025-11-05 04:53
油腻代码大叔与蝴蝶效应2025-11-05 04:40
如何让网站用上HTML5 Manifest2025-11-05 04:38
以k快启动安装教程(轻松安装k快启动,提升系统启动速度)2025-11-05 04:28
跨国互联网公司并购中 用基础设施即代码进行架构迁移2025-11-05 04:23