缓存穿透-缓存雪崩-热点key

一、缓存穿透

  1. 概念

        缓存穿透是指查询一个数据库一定不存在的数据,从而导致未缓存相应的数据,最终每次请求都会访问数据库。

  1. 解决方案
    • ①用一个bitmap和n个hash函数做布隆过滤器过滤没有在缓存的键
    • ②持久层查询不到就缓存空结果,有效时间为数分钟。具体是通过某个特定值key去查询数据,如果数据库中不存在则缓存肯定不存在。此时在缓存中设置此特定值key,将其对应的value设置为一个默认的值(如“NULL”),并设置一个失效时间。在当前缓存失效之前,所有通过此key的访问都被缓存挡住了。如果此key对应的数据存在时,在缓存失效之后,通过此key再去访问数据库从而设置新的value。

二、缓存雪崩

  1. 概念

        缓存雪崩是指在某一个时间段缓存集中过期失效,此时数据库访问量会瞬间增大,造成过大的压力。

  1. 解决方案

    • ①将系统中key的缓存失效时间均匀地错开,防止统一时间点有大量的key对应的缓存失效
    • ②优化缓存使用方式,当通过key去查询数据时,首先查询缓存,如果此时缓存中查询不到,就通过分布式锁进行加锁,取得锁的进程查DB并设置缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回缓存数据或者再次查询DB
    • ③通过队列实现串行化访问

三、热点key

  1. 概念

        热点key是指一个key非常热点(明星八卦新闻或商品大促销),大并发集中对这一个节点进行访问,当key失效的时候有大量线程来构建缓存,导致负载增加进而系统崩溃。

  1. 产生原因

    • ①用户消费的数据远大于生产的数据,如热卖商品、热点新闻等
    • ②请求分片集中,超过单 Server 的性能极限
  2. 解决方案

    • ①客户端热点key缓存:将热点key对应value并缓存在客户端本地,并且设置一个失效时间。每次读请求首先检查key是否存在于本地缓存中,如果存在则直接返回,如果不存在再去访问分布式缓存的机器。
    • ②将热点key分散为多个子key,然后存储到缓存集群的不同机器上,这些子key对应的value都和热点key是一样的。当通过热点key去查询数据时,通过某种hash算法随机选择一个子key,然后再去访问缓存机器,将热点分散到了多个子key上。
    • ③设置永不过期,包含两层意思:
      • redis确实没有设置过期时间,保证不会出现热点key过期问题,也就是“物理”不过期。
      • 从功能上把过期时间存在key对应的value里,如果发现要过期了,通过一个后台的异步线程进行缓存的构建,也就是“逻辑”过期,为每个 value 设置一个逻辑过期时间,当发现超过逻辑过期时间后,会使用单独的线程去构建缓存。