缓存穿透、缓存雪崩和缓存击穿 及解决方案

在现代分布式系统中,缓存是提高系统性能的重要手段。然而,缓存的使用也可能引发一些问题,其中最常见的包括缓存穿透、缓存雪崩和缓存击穿。以下是对这三种现象的详细讲解。

1. 缓存穿透

定义

缓存穿透是指用户请求的数据在缓存中不存在,系统每次请求都需要访问后端数据库。这种情况会导致大量无效请求直接打到数据库,增加数据库的负担,影响系统性能。

原因

  • 高并发访问未命中的key:当大量请求同时查询一个不存在的资源时,所有请求都会直接访问数据库,造成性能瓶颈。

解决方案

  • 合法性校验:在请求到达缓存或数据库之前,进行参数的合法性校验,确保请求的key是有效的。例如,可以检查请求的ID是否在预定义的范围内。
  • 布隆过滤器:使用布隆过滤器来判断某个key是否存在于数据库中。布隆过滤器是一种空间效率高的概率型数据结构,可以快速判断一个元素是否在集合中。通过在请求到达数据库之前先查询布隆过滤器,可以有效减少对数据库的访问。

2. 缓存雪崩

定义

缓存雪崩指的是在特定时间内,大量缓存数据同时过期,或者缓存服务器宕机,导致大量请求直接打到数据库上,从而引发系统崩溃或性能急剧下降。

主要原因

  • 缓存服务器重启:当缓存服务器重启时,所有缓存数据会被清空,导致后续请求直接访问数据库。
  • 不当的缓存设置:如果多个缓存项设置了相同的过期时间,可能会导致它们在同一时刻失效。
  • 缓存与数据库不一致:在某些情况下,缓存中的数据可能与数据库中的数据不一致,导致请求直接访问数据库。

解决方案

  • 设置缓存过期时间随机性:通过对缓存的过期时间进行随机化,避免多个缓存项在同一时间失效,从而减少同时请求数据库的情况。
  • 熔断机制和限流降级:在高并发情况下,使用熔断器防止系统过载,同时可以对请求进行限流,确保系统能够稳定运行。

3. 缓存击穿

定义

缓存击穿是指一个热点key失效时,瞬间有大量并发请求直接访问数据库,导致数据库瞬间承受巨大的压力。

原因

  • 热点key在失效瞬间:当某个非常热门的key(例如,某个热门商品的详情)失效时,所有请求会同时尝试访问数据库,导致数据库负载过高。

解决方案

  • 加锁:在请求到达数据库之前,对热点key进行加锁,确保只有一个请求能够查询数据库并更新缓存,其他请求则等待。这样可以避免多个请求同时访问数据库。
  • 异步更新:在缓存失效时,异步更新缓存,允许请求先从数据库获取数据,同时更新缓存。这样可以减少对数据库的压力。
  • 布隆过滤器:同样可以使用布隆过滤器来判断请求的key是否存在,从而避免无效请求直接打到数据库。

总的来说

  • 缓存穿透:请求的数据在缓存和数据库中都不存在,导致每个请求都访问数据库。

  • 缓存雪崩:大量缓存同时失效,导致大量请求直接访问数据库。

  • 缓存击穿:某个热点数据的缓存失效,导致大量并发请求直接访问数据库。

4.布隆过滤器解决缓存穿透

布隆过滤器是一种高效的概率型数据结构,用于判断一个元素是否在集合中。布隆过滤器可以解决缓存穿透的原理如下:

  1. 提前将所有可能存在的请求 ID 添加到布隆过滤器中。
  2. 当有请求来时,先用布隆过滤器判断 ID 是否存在。
  3. 如果布隆过滤器说不存在,那肯定不存在。
  4. 如果布隆过滤器说存在,再去缓存和数据库查询。

这样即使缓存不命中,也可以快速判断大部分无效请求,只有可能存在的请求才会查询数据库。布隆过滤器的优点是空间效率和查询时间都很高。缺点是有一定的误判率(如果ID不存在,误判为存在的概率很小),且元素一旦加入就不能删除。所以布隆过滤器适合用于过滤掉大部分不存在的请求,减轻数据库压力。与缓存和数据库组合使用,可以有效防止缓存穿透。

5.加锁解决缓存击穿

加锁的思路是,当缓存失效时,控制只有一个请求去数据库查询数据并更新缓存,其他请求要么等待,要么直接返回一个默认值。这样可以保护数据库不被打垮。实现方式有两种:

  1. 互斥锁
    • 当缓存失效时,第一个请求获取到互斥锁,去数据库查询数据并更新缓存。
    • 其他请求等待,直到缓存更新完成。
    • 这种方式简单易懂,但需要自己实现分布式锁。
  2. 逻辑过期
    • 缓存数据除了值,还存储一个过期时间。
    • 当请求来时,先判断缓存是否过期,如果过期则开启一个后台线程更新缓存。
    • 主线程直接返回旧值。
    • 这种方式无需锁,但实现稍微复杂一些。

6.熔断解决缓存雪崩

熔断的思路是,当检测到缓存不可用或数据库压力过大时,快速返回一个默认值或错误信息,不再访问数据库。这样可以保护数据库不被打垮。实现方式有两种:

  1. 超时熔断
    • 设置数据库查询的超时时间。
    • 当查询超时时,快速返回一个默认值。
    • 这种方式简单易懂,但需要合理设置超时时间。
  2. 限流熔断
    • 限制数据库查询的并发数。
    • 当并发数超过阈值时,快速返回一个默认值。
    • 这种方式需要自己实现限流算法。
  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值