Redis缓存击穿、穿透、雪崩
1.缓存击穿
什么是缓存击穿
缓存击穿和缓存穿透从名词上可能很难区分开来,它们的区别是:穿透表⽰底层数据库没有数据且缓存内也没有数据,击穿表⽰底层数据库
有数据⽽缓存内没有数据。
当热点数据key从缓存内失效时,⼤量访问同时请求这个数据,就会将查询下沉到数据库层,此时数据库层的负载压⼒会骤增,我们称这种
现象为"缓存击穿"。
解决⽅案:
1.延长热点key的过期时间或者设置永不过期,如排⾏榜,⾸页等⼀定会有⾼并发的接⼝;
2.利⽤互斥锁保证同⼀时刻只有⼀个客户端可以查询底层数据库的这个数据,⼀旦查到数据就缓存⾄Redis内,避免其他⼤量请求同时穿
过Redis访问底层数据库;
importredis
fromtimeimportsleep
conn=('127.0.0.1')
defget(key,key_time,mutex_time):
value=(key)
print(value)
ifvalue==None:
key_mutex=key+"_nx"
#设置超时,防⽌del操作失败的时候,下次缓存过期⼀直不能loaddb
#待优化使⽤lua保证原⼦性避免死锁也就是说下列代码有死锁风险
(key_mutex,1)==1:
(key_mutex,mutex_time)
sleep(5)
value="我是查询数据"
(key,value,key_time)
(key_mutex)
returnvalue
el:
#这个时候代表同时候的其他线程已经loaddb并回设到缓存了,这时候重试获取缓存值即可
#TODO这⾥需要补充超时时间时间超过某个限制rai异常
sleep(0.1)
get(key,key_time,mutex_time)#重试
el:
returnvalue
2.缓存穿透
什么是穿透
当查询Redis中没有的数据时,该查询会下沉到数据库层,同时数据库层也没有该数据,当这种情况⼤量出现或被恶意攻击时,接⼝的访问
全部透过Redis访问数据库,⽽数据库中也没有这些数据,我们称这种现象为"缓存穿透"。
缓存穿透会穿透Redis的保护,提升底层数据库的负载压⼒,同时这类穿透查询没有数据返回也造成了⽹络和计算资源的浪费。
解决⽅案
1.在接⼝访问层对⽤户做校验,如接⼝传参、登陆状态、n秒内访问接⼝的次数;
2.利⽤布隆过滤器,将数据库层有的数据key存储在位数组中,以判断访问的key在底层数据库中是否存在;
PS:布隆过滤器有误判率,虽然不能完全避免数据穿透的现象,但已经可以将99.99%的穿透查询给屏蔽在Redis层了,极⼤的降低
了底层数据库的压⼒,减少了资源浪费。
3.缓存雪崩
什么是缓存雪崩
缓存雪崩是缓存击穿的"⼤⾯积"版,缓存击穿是数据库缓存到Redis内的热点数据失效导致⼤量并发查询穿过redis直接击打到底层数据库,
⽽缓存雪崩是指Redis中⼤量的key⼏乎同时过期,
然后⼤量并发查询穿过redis击打到底层数据库上,此时数据库层的负载压⼒会骤增,我们称这种现象为"缓存雪崩"。事实上缓存雪崩相⽐于
缓存击穿更容易发⽣,对于⼤多数公司来讲,
同时超⼤并发量访问同⼀个过时key的场景的确太少见了,⽽⼤量key同时过期,⼤量⽤户访问这些key的⼏率相⽐缓存击穿来说明显更⼤。
解决⽅案:
1.在可接受的时间范围内随机设置key的过期时间,分散key的过期时间,以防⽌⼤量的key在同⼀时刻过期;(PS:给key加⽇期,使⽤定
时任务将对应数据刷进redis缓存)
2.对于⼀定要在固定时间让key失效的场景(例如每⽇12点准时更新所有最新排名),可以在固定的失效时间时在接⼝服务端设置随机延
时,将请求的时间打散,让⼀部分查询先将数据缓存起来;
3.延长热点key的过期时间或者设置永不过期,这⼀点和缓存击穿中的⽅案⼀样;
本文发布于:2023-01-03 18:58:48,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/85990.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |