Redis缓存穿透、击穿、雪崩介绍以及解决方案

devtools/2025/2/6 21:24:16/

一、缓存穿透

1.1 什么是缓存穿透

指的是,外部进来的请求,查询一个不存在的数据。Redis中没有,数据库中也没有,这时候如果外部恶意大量请求,所有请求会直接查询数据库,导致数据库崩溃

1.2 解决方案

1.2.1 方案一:缓存空数据

缓存空数据到redis中,比如恶意请求查询编号为1的用户,我查询数据库后发现不存在,就直接在redis中添加键值对:{key: 1, value: null},这样外部再次大量请求也会直接请求在redis上,不会导致数据库异常

优点:简单

缺点:1、如果有大量的随机查询,比如查询编号为1,2,3,4,5......到一万亿的用户,我都保存一个键为编号,值为null的数据,那么对redis的内存压力也是很大的,保存了太多无用数据

2、如果编号为2的用户本来不存在,我现在在redis中设置了一个null的值;如果这个时候真的添加了这个编号为2的用户,那么外部查询也查询不到了:数据不一致

1.2.2 方案二:布隆过滤器

布隆过滤器是指,将键经过多次hash之后以0和1的数组格式,保存在一个位图(bitmap)中,一个请求进来,先把请求中查询的键去位图里查询,如果存在,再去查询Redis,如果不存在则连redis都不会去查,直接返回;

优点:位图bitmap占用内存较小,不像缓存空数据那样缓存大量的不需要的key

缺点:1、实现起来复杂,热点数据从数据库查询出来后,也要写入过滤器中

2、存在误判,如果一个不存在的数据,多次hash之后,在位图中的位置可能显示存在此条数据;导致查询数据库,但是总体上影响不大,误判率可自己在写代码时进行控制

二、缓存击穿

2.1 什么是缓存击穿?

当给某一个热点数据,设置了过期时间,当key过期时,恰好这段时间有大量的并发请求进来,那么可能会把数据库压垮

疑问:key过期了,Redis中查询不到,会去数据库查询,查询完成后不是又会写入redis中吗?为什么会导致大量请求到数据库呢?

解答:查询数据库并写入redis也是需要时间的,有些写入redis的结果集,是需要多表查询的结果,比如需要50ms的,甚至几秒钟才能从数据库查询出来的,那么这段时间就太长了

2.2 解决方案

2.2.1 互斥锁

当key过期后,后进来获取该key的第一个线程,在redis中查询不到,未命中;获取一个互斥锁,然后去查询数据库,获取结果后写入缓存,并释放锁;这段时间内,其他所有线程未命中redis中的数据,尝试获取锁失败(因为锁被线程1拿到了),导致获取锁的等待

优点:强一致性,数据一定是最新最正确的

缺点:要等到线程1查询到,写入redis中并释放锁之后,其他线程才能查询这条键值对的数据

2.2.2 逻辑过期

热点key不设值过期时间,而是加一个逻辑过期时间的字段,用来描述这整条数据是否逻辑过期;

当某个线程1拿到这条数据后,发现逻辑过期时间,已经过期,那么会新开一个线程2去进行缓存重建;而线程1不等待缓存重建的结果,直接将过期的数据返回回去

如果此时有更多的线程3来获取key发现过期,尝试获取锁失败后,会直接返回过期的数据,并不会开启新线程来进行缓存重建,因为只需要一个线程2进行缓存重建就可以了

当线程2缓存重建完成后,再之后的线程4就能获取到最新的数据了

优点:高可用(不管数据一致不一致,先返回了再说),性能优

缺点:不能保证数据绝对一致

三、缓存雪崩

3.1 什么是缓存雪崩?

是指同一时间大量的缓存key同时失效,或者Redis服务宕机,导致大量请求打到数据库,导致数据库压力巨大

3.2 解决方案

3.2.1 不同的过期时间

给不同的key设置不同的过期时间,可随机设置过期时间

3.2.2 Redis集群部署

利用Redis集群提高服务的高可用性,例如哨兵模式、集群模式等

3.2.3 降级限流策略

redis之前添加降级限流策略,比如nginx、spring cloud gateway等,可以同时作为缓存穿透、击穿、雪崩的保底策略,不止是防范缓存雪崩

3.2.4 添加多级缓存

redis之前,使用其他caffeine缓存等来做一级缓存,Redis作为二级缓存

附上《缓存三兄弟》及其解决方案打油诗一首:

穿透无中生有key,布隆过滤null隔离

缓存击穿过期key,锁与非期解难题

雪崩大量过期key,过期时间要随机

                                        --黑马程序员

注:其中的“锁与非期解难题”中的非期指的是逻辑过期


http://www.ppmy.cn/devtools/156627.html

相关文章

C++多线程编程——call_once和单例模式

目录 1. 前言 2. call_once和once_flag 3. 后记 3.1 单例类的析构问题 3.2 饿汉式单例模式的线程安全问题 1. 前言 之前在讲解单例模式时,有提到懒汉式单例模式使用了双重检测Double-Checked Locking Pattern (DCLP)来解决多线程的安全访问问题。但是该方法也…

数据结构(AVL树、B-Tree、B+Tree)

AVL树 AVL树是一种自平衡的二叉搜索树,它的特点是每个节点的左子树和右子树的高度差(平衡因子)的绝对值不超过1。这种平衡性保证了AVL树在进行查找、插入和删除操作时都能保持较高的效率。 平衡因子 在AVL树中,每个节点都维护一…

MySQL--》日志与主从复制的实战技巧

目录 日志 错误日志 二进制日志 查询日志 慢查询日志 主从复制 日志 日志:是记录数据库操作和事务的文件,主要用于帮助数据库管理员(DBA)跟踪、恢复数据以及进行故障排查,日志是MySQL数据库管理中非常重要的一部分,常见的日…

C基础寒假练习(2)

一、输出3-100以内的完美数&#xff0c;(完美数&#xff1a;因子和(因子不包含自身)数本身 #include <stdio.h>// 函数声明 int isPerfectNumber(int num);int main() {printf("3-100以内的完美数有:\n");for (int i 3; i < 100; i){if (isPerfectNumber…

【NLP251】NLP RNN 系列网络

NLP251 系列主要记录从NLP基础网络结构到知识图谱的学习 &#xff11;.原理及网络结构 &#xff11;.&#xff11;&#xff32;&#xff2e;&#xff2e; 在Yoshua Bengio论文中( http://proceedings.mlr.press/v28/pascanu13.pdf )证明了梯度求导的一部分环节是一个指数模型…

日本工作面试基本礼仪-一篇梗概

面接の内容に加えて、エチケットも非常に重要です。日本のビジネス社会には独自のビジネスマナー&#xff08;ビジネスマナー[ビジネスマナー]&#xff09;があり、国際基準とは異なる場合がありますので、注意が必要です。 日本人、特に日本の伝統的な大企業の面接官は、一般…

熟练掌握Http协议

目录 基本概念请求数据Get请求方式和Post请求方式 响应数据响应状态码 基本概念 Http协议全称超文本传输协议(HyperText Transfer Protocol)&#xff0c;是网络通信中应用层的协议&#xff0c;规定了浏览器和web服务器数据传输的格式和规则 Http应用层协议具有以下特点&#…

【开源免费】基于SpringBoot+Vue.JS美食推荐商城(JAVA毕业设计)

本文项目编号 T 166 &#xff0c;文末自助获取源码 \color{red}{T166&#xff0c;文末自助获取源码} T166&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…