美文网首页
Redis之缓存穿透、缓存击穿、缓存雪崩

Redis之缓存穿透、缓存击穿、缓存雪崩

作者: 江月照我眠 | 来源:发表于2022-01-31 11:11 被阅读0次

    一、缓存穿透

    场景描述:

    用户访问了一个数据库和缓存中都不存在的数据,此时不但会直接访问到数据库上,并且还无法查询到数据,因此没办法写缓存,这就造成下一次访问依然会重复上面的情况。此时缓存无法奏效,缓存就像被“穿透”了,每次都会直接访问数据库,一旦流量大时数据库很可能因无法承受压力而宕机。

    解决方案:
    1. 接口校验

    一般情况下,用户访问的都是我们提供的页面,应该不存在大量访问不存在的key的情况,所以出现这种情况很可能是遭受了非法的网络攻击,我们应该在接受请求的时候增加用户鉴权数据合法性校验等手段。

    2. 缓存空值

    当缓存和数据库都查不到值时,可以将空值写进缓存,但是设置一个较短的过期时间,根据实际情况调整。

    3. 布隆过滤器

    将所有可能存在的key存入布隆过滤器,布隆过滤器可以查询出其内部一定不存在的某个值,这样可以把不存在的key直接过滤掉,只有可能存在的key才会访问缓存和数据库。

    布隆过滤器相比HashMap占用空间更小,因此布隆过滤器通常是最佳选择。

    二、缓存击穿

    场景描述:

    假如有某个热点key,在缓存过期的一瞬间,同时有大量的访问请求涌入,由于缓存过期,请求最终会直接打进数据库,瞬时的巨大的访问量可能造成数据库因压力过大而崩溃。

    解决方案:
    1. 加互斥锁

    在并发的多个请求中,只有第一个请求能拿到锁并执行数据库查询操作,其他拿不到锁的线程就阻塞等着,等到第一个线程将数据写入缓存,后续请求就可以直接走缓存了。

    • 分布式锁(redis)
    • 进程锁(文件锁)

    注意:无论使用哪种锁,加锁时要按key维度去加锁,以实现多进程锁,否则不同的key之间还相互阻塞,会造成性能严重下降。

    2. 热点数据不过期

    直接将热点数据设置为永不过期,然后由异步任务去刷新缓存,这种方式只适用于流量特别巨大的场景。由于要隔一段时间才能刷新缓存,因此还要业务上还要考虑是否能接受一定时间内的数据不一致。

    三、缓存雪崩

    场景描述:

    大量热点key设置了相同的过期时间,导致缓存在同一时间失效,瞬时的巨大访问量直接请求到数据库上,数据库因压力大增造成雪崩甚至宕机。

    其实一眼看就知道这就是升级版的”缓存击穿“罢了,在上述解决方案的基础上,我们的解决方案也差不多。

    • 加互斥锁:同上。
    • 热点数据不过期:同上。
    • 过期时间打散:可以在缓存的过期时间上加一个随机时间,使得他们的过期时间分布开来,不至于同一时间失效。

    相关文章

      网友评论

          本文标题:Redis之缓存穿透、缓存击穿、缓存雪崩

          本文链接:https://www.haomeiwen.com/subject/raxhkrtx.html