缓存穿透

  • 大量请求的key根本不存在于缓存中,导致请求直接到了数据库上,根本没有经过缓存这一层。大多属于恶意攻击。
  • 解决:布隆过滤器
  1. 布隆过滤器。将所有可能存在的请求的值都存放在布隆过滤器中,当用户请求过来,先判断用户发来的请求的值是否存在于布隆过滤器中。不存在的话,直接返回请求参数错误信息给客户端,存在的话才会走下面的流程。
  2. 布隆过滤器说某个元素存在,小概率会误判。布隆过滤器说某个元素不在,那么这个元素一定不在。
  3. 利用Guava中自带的布隆过滤器。
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>28.0-jre</version>
    </dependency>
    
  4. 缺点:只能单机使用,不适用于分布式的场景。解决这个问题,需要使用redis中的布隆过滤器Module。

布隆过滤器

数据结构:位数组(bitSet)  + 多个哈希函数;
原理:
  • 元素加入布隆过滤器的时候:使用布隆过滤器中的哈希函数对元素值进行计算,得到哈希值(有几个哈希函数得到几个哈希值),根据得到的哈希值,在位数组中把对应下标的值置为1;
  • 判断一个元素是否在布隆过滤器中:对给定的元素再次进行相同的哈希计算,得到值后判断位数组中的每个元素是否都为1,如果值都为1,说明这个值在布隆过滤器中,如果存在一个值不为1,说明该元素不在布隆过滤器中。

缓存雪崩

  • 缓存在同一时间大面积的失效(key存储的时间到了)、或者意外出现了全盘宕机,后面的请求都直接落在了数据库上,造成数据库短时间内承受大量请求。
解决办法:
  • 采用redis集群,避免单机出现问题整个缓存服务都没办法使用。
  • 限流,避免同时处理大量的请求。
  • 生成key为随机时间

缓存击穿

  • 某个key非常热点,访问非常频繁。处于集中式高并发访问的情况,当key在失效的瞬间,大量请求就击穿了缓存,直接请求数据库
解决办法:
  • 热点数据设置永远不过期;