缓存穿透
缓存穿透(查不到):查询一个数据时Redis内存数据库没有,缓存未命中,于是向持久层数据库查询发现也不存在,查询失败。当多次缓存未命中时,都去请求持久层数据库造成压力,若用此进行攻击可能压垮数据库。
解决方案
- 布隆过滤器
布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,先在控制层进行校验,不符合则丢弃,从而避免对持久层的查询压力。 - 缓存空对象
缓存未命中后,把返回的空对象写入缓存同时设置一个过期时间,之后再访问时就能直接从缓存读取,保护持久层,但会耗费内存资源。
缓存击穿
缓存击穿(查得到但量太大,或缓存过期):顾名思义就像子弹盯着一个点打最后在这个点把墙击穿一样,缓存击穿是缓存中可以查询到这个key,但高并发的持续查询这个key时,穿透了缓存直接请求到持久层数据库,瞬间压力而崩溃。比如热点数据过期的瞬间(60s),请求数据库回写缓存时(60.1s),这0.1s的大量请求瞬间压垮数据库,例微博热搜崩溃 。
解决方案
- 设置热点数据永不过期
没有过期时间便不会出现上述问题,但会占据内存。 - 加互斥锁
使用分布式锁,保证每个key同时只有一个线程去查询持久层数据库,其余线程没有分布式锁权限只能等待(即把击穿后的请求加锁等待)从而避免数据库压力,但对分布式锁有一定考验。
缓存雪崩
缓存雪崩:指某一个时间内,缓存集中过期失效、Redis宕机、服务器重启、断电断网等缓存不可用的情况(Redis缓存崩溃了雪崩了)。然后所有请求直接打到后端数据库上,然后你懂的。
解决方案
- Redis高可用
提高Redis高可用性,使用主从复制、集群等保证一台redis挂掉,其余几台仍可继续正常工作。 - 限流降级
在缓存失效后,通过加锁或队列来控制线程数量,比如每个key只允许一个线程读写,其余等待。 - 数据预热
在正式部署前,把可能访问的数据线预先访问一遍,把部分可能大量访问的数据加载到缓存中,设置不同过期时间,让缓存失效时间点均匀分散。避免用户请求的时候再去加载相关的数据。
原创不易,请勿转载(
本不富裕的访问量雪上加霜)
博主首页:https://blog.csdn.net/qq_45034708
如果文章对你有帮助,记得关注点赞收藏❤