缓存击穿
概念:如果一个数据是热点数据,也就是经常被访问的数据,它在数据库是有存储的,此时它的缓存失效了,那么在失效那一刻就会有大量的请求进来直接进入到数据库,造成数据库压力增大。
解决方案
- 设置热点数据永不过期,定时任务更新缓存
- 设置互斥锁,只能有一个请求进入数据库拿到数据,然后将数据缓存到redis,之后的请求都从redis中获取。
这里顺带一提,如果是在分布式的情况下出现并发竞争热点key,并且要对key进行操作的话,就要使用分布式锁了,详见另一篇文章。
缓存雪崩
概念:由于设置了相同的过期时间,导致在同一时间有大量的热点key过期,此时进来的所有请求都会直接访问数据库,给数据库造成大量请求、导致数据库崩溃
解决方案
- 存数据的时候设置过期时间随机,防止同一时间大量数据过期的现象发生
- 设置热点数据永远不过期,定时任务定时更新
缓存穿透
概念:其实就是查询不存在的数据,比如请求id为-1的数据,缓存中是不存在的,此时就会去数据库查找。由于在数据库中也找不到该数据,说明该数据没有意义,也就不会将该数据缓存,所以 每次请求都会去数据库查找,当大量请求到数据库的时候,数据库可能就挂了。
解决方案
- 接口层增加校验逻辑,数据合理性校验
- 缓存中和数据库中都取不到数据的时候,可以讲key-value写为key-null存入redis,设置很短的过期时间,防止被同一个key一直攻击。
- 使用布隆过滤器,但是有缺点,就是有可能会误判,它是通过hash运算来确定是否有值,有可能运算结果正确,但其实并没有值。