缓存穿透、缓存击穿、缓存雪崩的场景以及解决方法
都是缓存惹的祸
在项目开发中,我们的数据都是要持久化到磁盘中去,比如使用 MySQL进行持久化存储,但是呢由于流量越来越大,查询速度也逐渐变慢了起来,于是我们决定!使用缓存!然而使用缓存导致会经常面临三座大山!缓存穿透!!缓存击穿!!缓存雪崩!!,接下来我们将会逐一分析他们导致的原因以及解决方法。
缓存雪崩
介绍
缓存雪崩是指在某个时间点,大量缓存同时失效或被清空,导致大量请求直接打到数据库或后端系统,造成系统负载激增,甚至引发系统崩溃。这通常是由于缓存中的大量数据在同一时间失效引起的。想象一个在线电商系统,用户访问频繁,需要频繁查询商品信息。假设某一系列的商品突然全部同一时间失效,那就会造成我们的缓存雪崩。或者某一个时刻 Redis 缓存中间件故障了,导致服务全部打到了数据库,也会导致缓存雪崩的情况。
解决办法
缓存键同时失效:
1)过期时间随机化:设置缓存的过期时间,加上一个随机值,避免同一时间大量缓存失效。
2)使用多级缓存:引入多级缓存机制,如本地缓存和分布式缓存相结合,减少单点故障风险。
3)缓存预热:系统启动时提前加载缓存数据,避免大量请求落到冷启动状态下的数据库。
4)加互斥锁:保证同一时间只有一个请求来构建缓存,别的只能等它构建完成再从缓存中读取。
缓存中间件故障:
1)服务熔断:暂停业务的返回数据,直接返回错误。
2)构建集群:构建多个 Redis 集群保证其高可用。
缓存击穿
介绍
缓存击穿是指针对某一热点数据的大量请求导致缓存失效,进而直接请求数据库,增加数据库负载。这种情况通常发生在某个特定的缓存 key 在失效时,恰好有大量请求到达。想象一下大家都在抢茅台,但在某一时刻茅台的缓存失效了,大家的请求打到了数据库中,这就是缓存击穿,那他跟缓存雪崩有什么区别呢?缓存雪崩是多个 key 同时,缓存击穿是某个热点 key 崩溃。也可以认为缓存击穿是缓存雪崩的子集,
解决办法
1)加互斥锁:保证同一时间只有一个请求来构建缓存,别的只能等它构建完成再从缓存中读取。跟缓存雪崩相同。
2)永久:不要给热点数据设置过期时间。
缓存穿透
介绍
缓存穿透是指查询一个不存在的数据,由于缓存和数据库中均不存在,导致每次请求都直接访问数据库增加数据库负载。攻击者可以通过构造不存在的 key 发起大量请求,造成系统宕机。比如有些小黑子对于我们开发的网站进行恶意的请求,将一些数据库不存在的 ID 疯狂的打在我们的服务器上,如果没做好缓存穿透的预防,还真给你们小黑子得逞了。
解决办法
1)防止非法请求:检查非法请求,封禁其IP 以及账号,防止它再次为非作歹。。
2)缓存空值:允许缓存空值或者可以给他一个默认值。
3)使用布隆过滤器:通过布隆过滤器给数据做一个标记,当发生缓存穿透时也不会请求数据库造成压力直接通过布降过滤器和 Redis 判断返回。