缓存预热、雪崩、击穿、穿透


缓存预热

概念

缓存预热是一种在程序启动或缓存失效之后,主动将热点数据加载到缓存中的策略。这样,在实际请求到达程序时,热点数据已经存在于缓存中,从而减少了缓存穿透和缓存击穿的情况,也缓解了SQL服务器的压力。


缓存雪崩

概念

当某一个时刻出现大规模的缓存失效的情况,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机。

出现大规模缓存失效的情况:

  • Redis服务器宕机(硬件运维)
  • 大量key同时过期(软件开发)

解决方案

  • Redis集群,避免单机宕机导致缓存失效
  • 在原有的失效时间上加上一个随机值,比如1-5分钟随机。这样就避免了因为采用相同的过期时间导致的缓存雪崩
  • 多缓存结合(本地缓存)
  • 服务降级,业务上兜底
  • 云数据库

缓存击穿

概念

其实跟缓存雪崩有点类似,缓存雪崩是大规模的key失效,而缓存击穿是一个热点的key,有大并发集中对其进行访问,突然间这个key失效了,导致大并发全部打在数据库上,导致数据库压力剧增。这种现象就叫做缓存击穿。


解决方案

  • 差异失效时间:

    在业务允许的情况下,对于热点的key可以设置永不过期

  • 互斥更新:

    采用双检加锁策略


缓存穿透

概念

一般情况下,先查询缓存Redis是否有该条数据,缓存中没有时,再查询数据库。当数据库也不存在该条数据时,每次查询都要访问数据库,这就是缓存穿透。

缓存穿透带来的问题是,当有大量请求查询数据库不存在的数据时,就会给数据库带来压力,甚至会拖垮数据库。


解决方案

  • 空对象缓存:

    增强回写,如果数据库查询不到数据,业务上规定某一特殊值回写进Redis。

    该方法有个缺陷是Redis中无关紧要的key会不断增多(一定要设置过期时间)

  • 布隆过滤器:

    把已存在数据的key存在布隆过滤器中,当有新请求时,先到布隆过滤器中查询是否存在:

    • 如果布隆过滤器中不存在该条数据,直接返回

    • 如果布隆过滤器中存在该条数据,再去查询缓存Redis,如果缓存中没有再去查询MySQL数据库