穿透:查询一个必然不存在的数据
- 每次请求都直接打到数据库
- 如果有人恶意攻击(比如查 id=-1),数据库会被打死
解决方案
- 缓存空对象:查不到也缓存一个 null,设置短过期时间
- 布隆过滤器:请求前先判断 key 是否存在,不存在直接返回
击穿:一个热点 key 过期瞬间,大量请求并发访问
解决方案:互斥锁
- 做法:当缓存过期后,在查询数据库之前,先尝试获取一个分布式锁。只有成功获取锁的线程才能去查询数据库并重建缓存;其他线程等待,然后从新缓存中获取数据。
- 优点:保证了最终一致性,实现相对简单。
- 缺点:会牺牲一点性能,因为有一小部分请求会等待。
雪崩:大量的key在同一时间大面积过期,大量的请求找不到缓存
解决方案:
1.设置随机过期时间:在设置缓存的过期时间时,不要设置成一样的,而是在一个基础时间上加上一个随机值(比如5分钟 ± 随机分钟),避免集体失效。
2.使用多级缓存:在应用层增加本地缓存(如Caffeine),作为Redis的备用。即使Redis挂了或过期,本地缓存还能顶一阵子。

No responses yet