1、缓存击穿
击穿,是从一个孔中击穿过去,意思就是有大量的请求同时请求一个缓存中没有的数据,数据库的压力瞬间暴增。
解决方案:
- 若缓存数据基本不变,则设置该热点数据永不过期。
- 使用分布式锁或的方式保证仅有一个请求去请求数据库,然后放入缓存,剩余的请求在锁释放后从缓存中获取。
- 使用定时任务在缓存过期前主动更新缓存。
2、缓存穿透
缓存中没有,数据库中也没有,所以每次请求都会去查询数据库,给数据库造成巨大压力。
场景:数据库主键都是 id>=0 的,恶意请求故意请求 id<=0 的值,导致每次都会查询数据库。
解决方案:
- 代码中主动判断 id 的正负。
- 没查到数据也放入缓存。
- 使用布隆过滤器。
3、缓存雪崩
缓存服务器重启或者大量缓存同时失效,导致数据库瞬间扛不住了。
解决方案:
- 互斥锁:使用互斥锁控制只能允许一个线程去DB中查询数据,然后放入缓存。
- 设置随机的过期时间:在原来失效的基础上增加一个随机值
- 缓存预热:系统上线前,先将数据加载到缓存系统,可以写一个缓存刷新页面,人工操作。