1. 缓存穿透
Redis作为缓存层,当用户访问某个数据时,首先会先在Redis缓存中进行查询,如果没有查询到,级没有缓存命中,接下来就会去数据库里面进行查询,若果查询到了就会写一份数据到Redis缓存中,但是结果 在Redis中和数据库中都查询不到 。这时当用户的请求量超出了数据库的最大承受量,则会导致数据库的面临崩溃。
解决方案:
- 缓存空值:不管数据库和缓存中是否存在该数据,都对该空结果进行缓存,只不过对其要设置较短的过期时间
- 用户合法性校验:对用户的请求合法性进行校验,拦截恶意重复请求。
- 使用布隆过滤器:它可以判断元素是否存在集合中,布隆过滤器可能存在一定误判的可能性,但它依然可以帮助你拦截掉大部分一定不存在的数据。
- 进行实时监控:当发现Redis缓存命中率急速下降时,迅速排查访问对象和访问数据,将其设置为黑名单。
2. 缓存击穿
简单来说,就是针对某个热点数据(频繁访问的数据)进行定点打击,才会使其被击穿了。
如果缓存中的 某个热点数据过期(失效) 了,此时大量的数据来访问该热点数据,无法从缓存中查询数据,那么就直接去数据库里面进行数据查询,高并发的访问数据库会导致数据库的崩溃。
解决方案:
- 对热点数据设置永不过期,由后台进行更新缓存
- 使用互斥性锁
- 实时调整数据过期时间
3.缓存雪崩
为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,在某一时刻,Redis缓存中 大量的热点数据都过期(失效) 或者 Redis故障宕机了,无法缓存命中,那么就去访问数据库,导致数据库崩溃。
解决方案:
-
构建多级缓存机制:nginx缓存 + redis缓存 + 其他缓存。
-
设置过期标志,后台更新缓存:记录缓存数据是否过期,如果过期会触发另外一个线程去在后台更新 实时缓存
-
将缓存可以时间分散:如在原有缓存时间基础上增加一个随机值,这个值可以在1-5分钟随机,这样过期时间重复率就会降低,防止大量key同时过期。
-
设置双key策略:主key设置过期时间,副key设置永不过期。
-
使用锁或队列机制:使用锁或队列保证不会有大量线程一次性对数据库进行读写,从而避免大量并发请求访问数据库,该方法不适用于高并发情况。