缓存雪崩,缓存穿透,缓存击穿

186 阅读2分钟

缓存雪崩

缓存某一时刻key大面积失效,导致大量的请求直接打到数据库上,在高并发量的情况下,可能导致数据库宕机,如果这时候重启数据库,还是会有新的流量瞬间压垮数据库。这就是缓存雪崩。

导致缓存的雪崩的原因
  • Redis服务器宕机,
  • 采用了相同的过期时间,导致大量缓存同时失效
解决方案
  1. 尽量避免redis宕机,我们可以使用redis集群

  2. 错开过期时间,让缓存失效的时间尽可能均匀,避免大量的key同时失效

  3. 分级缓存:既然缓存会失效我就再加一层缓存,没层缓存失效的时间不同

  4. 热点数据用不过期

    物理层面的不过期:热点key不设置过期时间
    逻辑层面:一旦key过期了,通过有个一异步线程加载缓存
    
  1. 采用互斥锁,一旦key失效只能有一个线程能Load DB.其他线程要么重试,要么返回。

缓存穿透:

指用户请求一个不存在的数据,所以每次都要请求DB,如果有恶意的攻击大量请求不存的数据,会造成数据库压力过大,甚至宕机。

解决方案
  1. 将无效的key也存到redis中,就算数据库差不多数据,我们也将这个key保存到redis中,value为null,并设置一个很短的过期时间,但是这种方式也有问题,比如可以是随机的,那么存进redis也没有意义,
  2. 使用布隆过滤器,布隆过滤器能判断一个key是否存在(可能会误判,存在的铁定存在,不存在的可能会判断成存在,但是误判的概率不大)。请求缓存之前会找布隆过滤器判断key是否存在,不存在就直接返回。从而降低了数据库的压力。

缓存击穿

缓存击穿和缓存雪崩有点类似,他们的区别在于缓存雪崩是缓存大面失效,缓存击穿是某些个热点key失效,但是热点key的请求量巨大,导致请求大量的压到了数据库。造成数据库压力过大甚至宕机,

解决方案(同缓存雪崩)
  1. 还是互斥锁
  2. 热点数据用不过期