【Redis】缓存的穿透、击穿和雪崩

引言

要了解缓存的这几个相关问题,我们先以一个例子来引入:

有一个get请求:

复制代码
api/news/getById/1

正常情况下对其申请访问的流程如图:

但若是如此,访问增多或者受到攻击时很容易受到以下问题

1 缓存穿透

1.1 造成原因

当查询一个不存在的数据时,MySQL查询不到数据,也不会直接写入缓存,导致每次请求都会查询数据库

1.2 解决方案

1.2.1 方案一 缓存空数据

缓存空数据,查询返回的数据为空,仍将该结果保存,也就是保存null数据
优点:简单

缺点:消耗内存,且当数据库中的数据更新后,可能使得缓存与数据库中的数据不一致

1.2.2 方案二 布隆过滤器

先解释一个概念:bitmap(位图)

bitmap相当于一个以bit为单位组成的数组,每个单元只能存储二进制数0或1

布隆过滤器作用:检索一个元素是否在一个集合中

比如:

但是当数组大小有限时,就会出现类似哈希冲突的问题:

此时可以发现,如果id为3的数据不存在时,用布隆过滤器时会造成误判

可以得出,数组越大,布隆过滤器误差越小,但同时带来更多的内存消耗

如何调整其误判率呢?

可以通过Redisson或者Guava来设置误判率,通常将误判率设置在5%以下

2 缓存击穿

2.1 造成原因

给某个key设置了过期时间,当该key过期时,恰好对其有大量并发请求,这些并发请求可能瞬间将数据库压垮

2.2 解决方案

2.2.1 方案一 互斥锁

特点:数据强一致性能差,可在银行系统中使用

2.2.2 方案二 逻辑过期

特点高可用,但不能保证数据完全一致

性能优,可在秒杀功能中使用

3 缓存雪崩

3.1 造成原因

同一时段大量key同时失效或Reids服务器宕机,导致大量请求到达数据库,给数据库带来巨大压力

3.2 解决方案

1.给不同key的TTL添加随机值

2.利用Redis集群提高服务可用性,如哨兵模式和集群模式

3.给缓存业务添加降级限流策略,如nginx或spring cloud gateway

4.给业务添加多级缓存,如Guava或Caffeine
给缓存业务添加降级限流策略可作为保底策略,穿透、击穿、雪崩均适用

相关推荐
油丶酸萝卜别吃4 分钟前
Redis 布隆过滤器快速实现
数据库·redis·缓存
深念Y5 分钟前
stable-diffusion.cpp 的 FLUX.2 Klein 9B 分步
java·前端·数据库
whn19778 分钟前
oracle 的ora-19633处理
数据库·oracle
小弥儿17 分钟前
Firecrawl:把整个网页变成 AI 可查询的数据库
数据库·人工智能·学习
MC皮蛋侠客19 分钟前
TDengine C++ 系列(8):流式计算与最新值缓存——库内实时处理
c++·缓存·tdengine
swordbob25 分钟前
mysql数据库,明明有索引为啥不用
数据库·mysql
晴天¥1 小时前
Oracle ASM、ACFS、FLEX ASM三者之间的关系?
数据库·oracle
Leon-Ning Liu1 小时前
Oracle GoldenGate Replicat Abend:Key Column Missing 根因分析与修复
数据库·oracle
IvorySQL11 小时前
PostgreSQL 日报 | JOIN 与外键优化(8 月 9 日)
数据库·postgresql
ltl11 小时前
自治数据库十年回顾:Peloton、NoisePage、OtterTune 到云原生 auto-tuning
数据库