什么是缓存雪崩,击穿,穿透?


1.缓存雪崩

为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并将数据更新到 Redis 里,这样后续请求都可以直接命中缓存。

image-20230216202530094

大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。

发生缓存雪崩的原因有两点

  • 大量数据同时过期
  • Redis 故障宕机

大量数据同时过期解决方案

  • 均匀设置过期时间

过期时间加上随机数,避免大量数据同时过期

  • 互斥锁

设置互斥锁并且设置超时时间,保证同一时间内只有一个请求来构建缓存

  • 双 key 策略

设置两个key缓存数据,主 key,会设置过期时间备 key,不会设置过期,访问不到主Key,直接返回备Key的数据,然后在更新缓存的时候,同时更新「主 key 」和「备 key 」的数据。

  • 后台更新缓存
  • 业务线程不再负责更新缓存,缓存也不设置有效期,而是让缓存“永久有效”,并将更新缓存的工作交由后台线程定时更新

Redis宕机解决方案

  • 服务熔断或请求限流机制;

启动服务熔断机制,暂停业务应用对缓存服务的访问,直接返回错误,不用再继续访问数据库,从而降低对数据库的访问压力,保证数据库系统的正常运行,然后等到 Redis 恢复正常后,再允许业务应用访问缓存服务。

  • 构建 Redis 缓存高可靠集群;

服务熔断或请求限流机制是缓存雪崩发生后的应对方案,我们最好通过主从节点的方式构建 Redis 缓存高可靠集群

2.缓存击穿

如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮,这就是缓存击穿的问题。

image-20230216203832131

解决方案

  • 互斥锁

保证同一时间只有一个业务线程更新缓存,未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。

  • 不给热点数据设置过期时间

由后台异步更新缓存,或者在热点数据准备要过期前,提前通知后台线程更新缓存以及重新设置过期时间。

3.缓存穿透

当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。

image-20230216204046635

发生缓存击穿的两种情况:

  • 业务误操作,缓存中的数据和数据库中的数据都被误删除了,所以导致缓存和数据库中都没有数据;
  • 黑客恶意攻击,故意大量访问某些读取不存在数据的业务;

缓存击穿解决方案

  • 非法请求的限制
  • 缓存空值或者默认值
  • 使用布隆过滤器快速判断数据是否存在,避免通过查询数据库来判断数据是否存在

image-20230216204346526

参考资料: 小林coding


  目录