Redis中雪崩,穿透,击穿

在 Redis 中,雪崩穿透击穿是三种常见的缓存问题,理解它们的区别和应对策略是保障系统高可用性的重要方面。下面结合具体场景对这三种问题进行详细讲解。

1. 缓存雪崩

定义

缓存雪崩是指大量缓存在同一时间内失效,或者缓存服务不可用,导致所有请求直接打到数据库,造成数据库压力激增,甚至可能导致系统崩溃。

原因
  • 缓存集中过期(例如,大量缓存数据设置了相同的过期时间)。
  • Redis 服务不可用。
场景示例

假设你在一个电商网站上为商品详情设置了缓存,每个商品的缓存有效期为24小时。如果某天你同时为多个商品生成缓存,并且设置的过期时间相同,那么当24小时到期时,这些商品的缓存会同时失效。在这种情况下,所有访问商品详情的请求将无法命中缓存,直接涌向数据库,可能导致数据库压力过大,响应变慢,甚至宕机。

解决方案
  • 缓存过期时间随机化:设置缓存时为每个缓存增加一定的随机偏移时间(如24小时±1小时),避免同一时间大量缓存失效。
  • 缓存预热:在系统启动时,提前将常用或重要的数据加载到缓存中,确保高峰期不容易出现缓存大面积失效。
  • 双层缓存:在 Redis 之外,再使用本地缓存(如 JVM 缓存)作为二级缓存,降低对数据库的直接访问。
  • 限流降级:当缓存失效时,实施限流策略控制访问频率,或者返回默认值,避免系统崩溃。

2. 缓存穿透

定义

缓存穿透指的是请求的某些数据在缓存和数据库中都不存在,由于缓存不命中,直接将请求打到数据库,且恶意请求往往会通过大量查询不存在的 key,造成数据库压力。

原因
  • 恶意请求(如请求大量不存在的 ID)。
  • 用户误操作,导致大量查询不存在的数据。
场景示例

假设你有一个用户信息查询接口,接口通过用户ID从 Redis 获取用户信息。如果有用户传入了一个根本不存在的用户ID(例如一个非常大的随机数ID),Redis 没有命中缓存,查询直接打到数据库。恶意用户可能通过伪造大量无效的 ID 发起请求,导致大量请求绕过缓存进入数据库。

解决方案
  • 缓存空值:对于查询结果为空的请求,将该结果也缓存起来,并设置一个较短的过期时间(如 5 分钟),避免短时间内对相同的无效请求重复查询数据库。
  • 布隆过滤器:在缓存层之前引入布隆过滤器,用于快速判断 key 是否存在,拦截不存在的数据请求,避免打到数据库。
  • 参数校验:对请求参数进行合理性检查,过滤掉明显不合理的请求,避免直接查询数据库。

3. 缓存击穿

定义

缓存击穿是指某个热点数据的缓存失效,而且恰好有大量并发请求访问该数据,导致短时间内所有请求直接打到数据库,造成数据库压力激增。

原因
  • 某些热点数据缓存失效时,恰好有大量请求集中访问该数据。
场景示例

假设你在一个新闻网站上有一篇非常热门的文章,用户访问量非常大。该文章的缓存有效期为10分钟,当缓存到期时,有大量用户同时访问这篇文章,缓存失效的瞬间,所有请求都涌向数据库,短时间内对数据库产生巨大压力。

解决方案
  • 热点数据永不过期:对于热点数据,可以手动控制缓存的失效时间,或者直接设置成不过期,避免频繁失效。
  • 加锁/互斥机制:当缓存失效时,使用分布式锁机制(如 Redis 分布式锁),让只有一个请求去数据库查询和更新缓存,其余请求等待缓存更新完成,避免并发查询。
  • 缓存预热:提前将热点数据加载到缓存中,或者定时刷新缓存,确保热点数据不会在高并发时失效。
  • 降级策略:如果数据库压力过大,可以返回旧数据或者默认值,避免直接查询数据库,保障系统的稳定性。

结合场景对比三种问题

  1. 缓存雪崩
    • 场景:某电商网站的所有商品详情页缓存都设置了24小时的过期时间。过期时,数十万个用户同时请求商品详情,导致大量请求瞬间打到数据库。
    • 关键点:大量不同的数据缓存同时失效。
    • 解决方案:设置缓存过期时间时增加随机偏移,避免大量缓存同时过期。
  2. 缓存穿透
    • 场景:用户请求一个不存在的商品 ID,这个 ID 既不在缓存中也不在数据库中。用户通过大量伪造 ID 进行查询,导致所有请求都穿透缓存打到数据库。
    • 关键点:请求的数据在缓存和数据库中都不存在。
    • 解决方案:使用布隆过滤器过滤掉不存在的请求,或者将空结果缓存。
  3. 缓存击穿
    • 场景:新闻网站的某篇热点文章有大量用户同时访问。当缓存过期时,所有请求同时访问数据库查询该文章,造成数据库瞬时高压。
    • 关键点:某个热点数据的缓存失效,并发请求打到数据库。
    • 解决方案:为热点数据使用分布式锁,确保只有一个请求去查询数据库并更新缓存,其余请求等待缓存更新完成。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yymagicer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值