缓存穿透/缓存击穿/缓存雪崩 攻防录

54 阅读3分钟

缓存穿透/缓存击穿/缓存雪崩 攻防录

参考:什么是缓存击穿、缓存穿透、缓存雪崩?

参考:缓存的常见问题


回答

  1. 缓存穿透

    是指缓存服务器中没有缓存数据,数据库中也没有符合条件的数据

    导致业务系统每次都绕过缓存服务器查询下游的数据库,缓存服务器完全失去了其应有的作用

  2. 缓存击穿

    是指当某key的缓存过期时,大并发量的请求同时访问此 key,瞬间击穿缓存服务器直接访问数据库,让数据库处于负载的情况。

  3. 缓存雪崩

    是指当大量缓存同时过期或缓存服务岩机,所有请求的都直接访问数据库,造成数据库高负载,影响性能,甚至数据库岩机。

扩展

1、缓存穿透

image-20241219144613085

  1. 解决方案一、缓存空值

    之所以会发生穿透,就是因为缓存没有把那些不存在的值得Key缓存下来,从而导致每次查询都要请求到数据库。

    那么,我们就可以,为这些 key 对应的值设置为 null,并放到缓存中。这样再出现查询这个key的请求的时候,直接返回null即可。

    注意,空值缓存需要有一个失效时间

  2. 解决方案二、布隆过滤器(BloomFilter)

    一般来说,缓存穿透是因为有很多恶意流量的请求

    这些请求可能随机生成很多Key来请求查询,这些肯定在缓存和数据库中都没有,那就很容易导致缓存穿透针对类似的情况,可以使用一个过滤器。

    在解决缓存穿透问题上,常用的技术是布隆过滤器(BloomFilter)

    参考:Java 八股/22-高性能、高可用、高并发/布隆过滤器是什么?实现原理是什么?.md

    我们可以将查询的数据条件都哈希到一个足够大的布隆过滤器中,用户发送的请求会先被布隆过滤器拦截,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。

2、缓存击穿

image-20241219143522107

  1. 解决方案一、异步定时更新

    比如,某一个热点数据的过期时间是1小时。

    那么每59分钟,通过定时任务去更新这个热点key,并重新设置其过期时间。

  2. 解决方案二、互斥锁

    通常使用一个互斥锁来解决缓存击穿的问题。

    就是当Redis中根据key获得的value值为空时,先锁上。然后,从数据库加载,加载完毕,释放锁。

    若其他线程也在请求该key时,发现获取锁失败,则先阻塞。

3、缓存雪崩

image-20241219144105232

  1. 方案一、不同的过期时间

    为了避免大量的缓存在同一时间过期,可以把不同的key过期时间设置成不同的。

    并且,通过定时刷新的方式更新过期时间。

  2. 方案二、集群部署

    在缓存雪问题防治上面,一个比较典型的技术就是采用集群方式部署,使用集群可以避免服务单点故障