缓存穿透:
当大量的请求访问一个不存在的数据,因为缓存中没有,那么大量的请求直接访问我们的数据库,会降低我们数据库的查询效率甚至导致数据库宕机。
解决方案:

  1. 缓存一个空对象:当访问的数据不存在,那么就将这个数据写到缓存当中去,并且给数据设置一个带有过期时间的key,这样就可以避免大量的数据反复的去访问我们的数据库。
  2. 布隆过滤器:在将数据存储到Redis时,同时存储一个Redis的key到布隆过滤器当中,然后根据布隆过滤器中提供的Hash函数对key进行hash运算,再对位数组的长度取余,得到一个下标,将下表的值标记为1。然后让我们查询的时候,按Redis存储到布隆过滤器中的方法,去判断Redis的key是否在布隆过滤器中,如果一定存在,那么就直接返回了,如果可能存在,那么就先查询缓存中是否存在数据,如果不存在再访问我们的数据库。

缓存击穿:
当缓存中一个热点数据的key突然过期,那么访问热点数据的大量请求直接访问我们的数据库,也会造成数据库的性能下降或者宕机。
解决方案:

  1. 热点数据永不过期:写一个定时任务,每日的凌晨定时更新缓存中的数据,先将缓存中的数据删除,再查询数据,最后将查询当中的数据存入到缓存当中去。
  2. 接口限流或者熔断
  3. 分布式锁:因为在分布式环境下,传统的锁会失效,因为传统的锁时基于JVM的。
    分布式锁分为:Zookeeper和Redission
    我们项目中使用的是Redission,虽然性能不如ZK,但是我们项目中已经引入的Redis,使用Redission就不需要动我们项目整体的架构,而且我们项目中对分布式锁的要求没有那么高。

缓存雪崩:
缓存中的数据大量的key同一时间突然过期,那么大量请求也会直接访问我们的数据库,导致数据库的性能降低或者直接宕机。
解决方案:

  1. 热点数据永不过期
  2. 分布式锁
  3. 给缓存中的key设置一个随机过期的时间,比如缓存中的数据的key存活时间为30分钟,写一个0-100之间的随机数加入到缓存时间当中去。