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

缓存雪崩

当缓存中大量的键值对同时过期或者Redis宕机了,大量的请求就会直接打到数据库,这种现象就是缓存雪崩

应对策略

有四种,分别是“均匀设置过期时间”、“互斥锁”、“双key策略”、“设置逻辑过期时间,异步更新缓存”

  • 均匀设置过期时间

可以在设置过期时间的时候,给时间加上随机数,防止大量数据同时过期

  • 互斥锁

发现无法命中缓存后,加上一个互斥锁,保证同于时间只有一个请求来构建缓存,其它没有获取到互斥锁的请求就会被阻塞。另外,最好给互斥锁加上超时时间,这样如果获取到锁的的请求由于某种意外一直不释放锁,就会让其它请求一直阻塞,整个系统就会出现无响应的状态。当然,加了锁就会影响并发量。

  • 双key策略

主key设置过期时间,备key不设置过期时间。当发现主key失效时,直接返回备key。

  • 设置逻辑过期时间,异步更新缓存

如果对缓存的一致性要求不高,那么可以不给键值对设置过期时间,而是设置一个逻辑过期时间。一个线程查询缓存发现逻辑过期时间已过期,获得互斥锁,接着会创建新的线程进行数据库查询与缓存重建以及逻辑过期时间的更新,在释放互斥锁之前,其它线程查询缓存未命中时,获取互斥锁失败后会直接返回过期数据
缓存雪崩、缓存击穿、缓存穿透_第1张图片

  • 构建缓存高可用集群(针对Redis宕机)
  • 服务熔断或者请求限流(针对Redis宕机)

服务熔断是说,Redis宕机后,直接拒绝缓存服务,也不会去访问数据库,直到redis重启之后,再运行业务对缓存进行访问。
请求限流是指Redis宕机后只允许发送少量请求到数据库,其余的请求都会被拒绝,直到Redis重启并把缓存预热完,再解除请求限流。

缓存击穿

缓存击穿是指某个热点key过期后,大量请求直接打到数据库,给数据库造成巨大压力

应对策略

和“缓存雪崩”类似,可以采用互斥锁或添加逻辑过期时间

缓存穿透

缓存雪崩和缓存击穿都可通过查询数据库进行缓存重构,但是缓存穿透就不一样了,它是缓存中没有数据,数据库中也没有数据。也就是没有办法进行缓存重构,很多请求会不断地打到数据库。

  • 产生的两个原因
  1. 业务的误操作,把缓存和数据库中的数据都删除了
  2. 黑客恶意的攻击,故意访问一些不存在的数据

应对策略

  1. 对请求的参数进行校验判断,看看是否为非法参数,对恶意请求返回错误
  2. 缓存空值。当发现缓存和数据库都查询不到数据时,缓存一个空值,这样后面的请求访问这个数据时,就会直接返回一个空值,而不会打到数据库
  3. 使用布隆过滤器

布隆过滤器可以判断一个数据是否存在于数据库当作。在进行业务操作的时候,如果缓存和布隆过滤器中都判断不存在这个数据,那么证明这个数据一定不存在于数据库,那么,就可以不用去数据库查找数据了。

  • 原理:

我们每次往数据库写入数据时,计算该数据的N个哈希函数值,然后分别与布隆过滤器(一个位图数组)的长度取模,得到位图上的编号,接着,这N个编号上的值置为1,这样后面查询数据是否在布隆过滤器,就可以对数据同样求N个哈希值,看看N个编号上是否都是1,是则说明数据库可能存在,不是则说明数据库一定不存在这个数据。缓存雪崩、缓存击穿、缓存穿透_第2张图片

对比

缓存雪崩、缓存击穿、缓存穿透_第3张图片

你可能感兴趣的:(Redis,缓存,java)