什么是缓存击穿、缓存穿透、缓存雪崩?怎么避免呢?

一、常见的缓存使用方式

读请求来了,先查下缓存,缓存有值命中,就直接返回;缓存没命中,就去查数据库,然后把数据库的值更新到缓存,再返回读取缓存

graph LR A(读请求来了) --> B{缓存有值命中?} B -- 是 --> C(直接返回缓存值) B -- 否 --> D{数据库有值?} D -- 是 --> E(更新缓存) E --> F(返回读取缓存) D -- 否 --> G(返回空值)

二、缓存穿透

指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力。

通俗点说,读请求访问时,缓存和数据库都没有某个值,这样就会导致每次对这个值✁查询请求都会穿透到数据库,这就是缓存穿透。

graph LR A(查询请求来了) --> B{缓存不存在?} B -- 是 --> D{数据库有值?} D -- 否 --> G(返回空值) G --> H(不写入缓存)

1、缓存穿透产生的几种情况

  • 业务不合理的设计,比如大多数用户都没开守护,但是你的每个请求都去缓存,查询某个userid查询有没有守护。

  • 业务/运维/开发失误的操作,比如缓存和数据库的数据都被误删除了。

  • 黑客非法请求攻击,比如黑客故意捏造大量非法请求,以读取不存在业务数据。

2、如何避免缓存穿透呢?

  • 如果是非法请求,我们在API入口,对参数进行校验,过滤非法值。

  • 如果查询数据库为空,我们可以给缓存设置个空值,或者默认值。但是如有有写请求进来的话,需要更新缓存哈,以保证缓存一致性,同时,最后给缓存设置适当过期时间。(业务上比较常用,简单有效)

  • 使用布隆过滤器或者布谷鸟过滤器快速判断数据是否存在。即一个查询请求过来时,先通过布隆过滤器或者布谷鸟过滤器判断值是否存在,存在才继续往下查。

三、缓存雪崩

指缓存中数据大批量到过期时间,而查询数据量巨大,请求都直接访问数据库,引起数据库压力过大甚至down机。

graph LR A(查询请求来了) --> B{缓存炸了?} B -- 是 --> D{数据库有值?} D -- 是 --> E(更新缓存) E --> F(返回数据库值) D -- 否 --> G(返回空值) G --> H(不写入缓存) H --> I{数据库是否不可用?} I -- 是 --> J(返回错误信息) I -- 否 --> K(尝试重新连接数据库) K --> D

1、缓存雪崩产生的几种情况及解决办法

  • 缓存雪奔一般是由于大量数据同时过期造成的,对于这个原因,可通过均匀设置过期时间解决,即让过期时间相对离散一点。如采用一个较大固定值+一个较小的随机值,5小时+0到1800秒酱紫。

  • Redis故障宕机也可能引起缓存雪奔。这就需要构造Redis高可用集群啦。

四、缓存击穿

指热点key在某个时间点过期时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db。

graph LR A(大量热点查询请求来了) --> B{缓存有值命中?} B -- 否 --> D{数据库有值?} D -- 是 --> E(更新缓存) E --> F(返回数据库值)

1、缓存击穿和缓存雪崩的区别

缓存击穿看着有点像缓存雪崩,其实它两区别是,==缓存雪奔是指数据库压力过大甚至down机,缓存击穿只是大量并发请求到了DB数据库层面==。可以认为击穿是缓存雪奔的一个子集吧。也可以认为它俩区别,是区别在于击穿针对某一热点key缓存,雪奔则是很多key。

2、缓存击穿的解决方案

  • 使用互斥锁方案:缓存失效时,不是立即去加载db数据,而是先使用某些带成功返回的原子操作命令,如(Redisetnx)去操作,成功的时候,再去加载db数据库数据和设置缓存。否则就去重试获取缓存。

  • 永不过期:是指没有设置过期时间,但是热点数据快要过期时,异步线程去更新和设置过期时间。

相关推荐
一匹电信狗7 小时前
【LeetCode_547_990】并查集的应用——省份数量 + 等式方程的可满足性
c++·算法·leetcode·职场和发展·stl
计算机毕设VX:Fegn08957 小时前
计算机毕业设计|基于springboot + vue蛋糕店管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
鱼跃鹰飞7 小时前
Leetcode会员尊享100题:270.最接近的二叉树值
数据结构·算法·leetcode
没差c8 小时前
springboot集成flyway
java·spring boot·后端
三水不滴8 小时前
Redis 过期删除与内存淘汰机制
数据库·经验分享·redis·笔记·后端·缓存
梵刹古音8 小时前
【C语言】 函数基础与定义
c语言·开发语言·算法
笨蛋不要掉眼泪8 小时前
Spring Boot集成LangChain4j:与大模型对话的极速入门
java·人工智能·后端·spring·langchain
筵陌9 小时前
算法:模拟
算法
We་ct9 小时前
LeetCode 205. 同构字符串:解题思路+代码优化全解析
前端·算法·leetcode·typescript
renhongxia19 小时前
AI算法实战:逻辑回归在风控场景中的应用
人工智能·深度学习·算法·机器学习·信息可视化·语言模型·逻辑回归