【Redis 缓存】核心问题篇(一文搞懂Redis穿透、击穿与雪崩的本质与解决方案)

「开学季干货」:聚焦知识梳理与经验分享 10w+人浏览 663人参与

一、缓存穿透(Cache Penetration)

定义

查询一个 “不存在的数据” 时,缓存中没有(未命中),数据库中也没有,导致每次请求都穿透缓存直达数据库,形成 “空查” 风暴。

核心原因

  • 数据本身不存在(如用户查询 ID=-1 的订单、不存在的商品 ID);

  • 恶意攻击(如伪造大量不存在的 key 发起请求,耗尽数据库资源)。

解决方案

1. 空值缓存(最常用)

对查询结果为null的数据,也缓存到 Redis 中,设置一个较短的过期时间(如 30 秒~5 分钟),避免同个不存在的 key 反复穿透。

  • 示例:查询商品 ID=9999(不存在),数据库返回 null,Redis 缓存key=product:9999, value=null, expire=60s

  • 注意:过期时间不能太长,避免 “真数据” 后续新增时,缓存中的空值遮挡真实数据。

2. 布隆过滤器(防海量空 key)

当存在大量不存在的 key(如恶意攻击)时,空值缓存会占用大量 Redis 内存,此时用布隆过滤器前置拦截:

  • 原理:布隆过滤器是一种空间高效的概率数据结构,存储 “数据库中已存在的 key”(如所有商品 ID、用户 ID)。查询前先过过滤器:

    • 若过滤器判断 “key 不存在”,直接返回 null,不查缓存和数据库;

    • 若过滤器判断 “key 可能存在”(存在极小误判率),再查缓存→数据库。

  • 优势:内存占用极低(存储 1 亿个 key 仅需约 12MB),查询速度快(O (1))。

  • 注意:存在误判率(可通过调整哈希函数数量和位数降低),且不支持删除操作(需定期重建)。

3. 业务层校验(源头拦截)
  • 对输入参数做合法性校验(如用户 ID 必须为正整数、商品 ID 在合理范围),直接拦截非法请求。

二、缓存击穿(Cache Breakdown)

定义

一个 “高频访问的热点 key” 突然过期(失效),此时大量请求同时穿透缓存直达数据库,导致数据库瞬间压力激增。

  • 注意:与穿透的区别 —— 击穿是 “数据存在,但缓存刚好过期”;穿透是 “数据本身不存在”。

核心原因

  • 热点 key 过期:如电商秒杀商品、热门新闻的缓存 key 到期;

  • 并发量极高:同一时间大量请求访问这个刚过期的热点 key。

解决方案

1. 热点 key 永不过期(简单粗暴)

对绝对热点的 key(如首页 Banner、秒杀活动商品),不设置过期时间,由业务层主动更新(如定时任务、数据变更时同步更新缓存)。

  • 风险:需确保热点 key 的数据变更能及时同步到缓存,避免数据不一致。

2. 互斥锁(分布式锁)

当缓存未命中时,通过分布式锁(如 Redis 的SET NX EX命令)保证 “只有一个请求能去查数据库”,其他请求阻塞等待,直到数据库查询结果写入缓存后再释放锁。

  • 流程:

    1. 请求查询 key,缓存未命中;

    2. 尝试获取分布式锁(SET lock:product:100 NX EX 5);

    3. 若获取锁成功:查数据库→写入缓存→释放锁;

    4. 若获取锁失败:休眠 100ms 后重试步骤 1(直到缓存命中)。

  • 优势:严格控制数据库访问,避免并发冲击;

  • 注意:锁的过期时间需大于数据库查询时间,避免锁提前释放导致并发问题。

3. 热点 key 过期时间 “错开”

对一批热点 key(如同一类商品),设置过期时间时增加随机偏移量(如基础过期 1 小时,加上 0~10 分钟随机值),避免大量热点 key 在同一时间集体过期。

三、缓存雪崩(Cache Avalanche)

定义

大量缓存 key 在同一时间集体过期,或 Redis 服务本身宕机,导致所有请求瞬间穿透到数据库,数据库因无法承受海量请求而宕机,形成 “缓存→数据库” 的连锁崩溃。

  • 注意:与击穿的区别 —— 击穿是 “单个热点 key 过期”,雪崩是 “大量 key 同时过期或缓存服务挂了”,影响范围更大。

核心原因

  1. 缓存 key 集中过期:如批量导入数据时,所有 key 设置了相同的过期时间(如凌晨 2 点);

  2. 缓存服务故障:Redis 集群宕机、网络中断等,导致缓存整体不可用。

解决方案

1. 过期时间 “随机化”(防集中过期)

同 “缓存击穿” 的方案 3,对所有 key 的过期时间添加随机偏移量,打散过期时间点,避免集体失效。

  • 示例:基础过期时间 = 3600s,实际过期时间 = 3600s + random (0, 600s)(10 分钟内随机)。

2. 缓存集群 “高可用”(防服务宕机)

通过 Redis 集群部署(如主从复制 + 哨兵模式、Redis Cluster),确保单个节点宕机时,从节点能快速切换为主节点,缓存服务不中断。

  • 主从复制:主节点写入,从节点同步数据并提供读服务;

  • 哨兵模式:监控主从节点,主节点宕机时自动选举从节点为主。

3. 多级缓存(降低缓存依赖)

引入 “本地缓存 + 分布式缓存” 的多级架构:

  • 本地缓存(如 Java 的 Caffeine、Guava Cache):存储最核心的热点数据,访问速度更快,且不依赖 Redis;

  • 分布式缓存(Redis):存储全量缓存数据。

  • 当 Redis 宕机时,本地缓存可临时承接部分请求,降低数据库压力。

4. 数据库 “限流 & 降级”(最后防线)

当缓存雪崩发生时,通过限流(如用 Sentinel、Gateway 限制每秒请求数)或降级(如返回默认数据、提示 “服务繁忙”)保护数据库,避免数据库宕机。

  • 示例:秒杀活动中,若 Redis 宕机,直接返回 “活动太火爆,请稍后再试”,不查数据库。

5. 缓存预热(提前加载数据)

在系统上线前或流量高峰前(如大促开始前 1 小时),通过脚本批量将热点数据加载到缓存中,避免高峰时段 “缓存未命中→查数据库” 的连锁反应。

三者对比总结

问题类型触发场景数据存在性影响范围核心解决方案
穿透查询不存在的 key不存在单个 key 的空查空值缓存、布隆过滤器、业务校验
击穿热点 key 突然过期存在单个热点 key互斥锁、热点 key 永不过期、随机过期
雪崩大量 key 集中过期 / 缓存宕机存在所有请求随机过期、缓存高可用、多级缓存、限流降级

通过理解三者的差异,可针对性地在业务中组合使用解决方案(如 “布隆过滤器防穿透 + 互斥锁防击穿 + 随机过期 + Redis 集群防雪崩”),构建高可用的缓存架构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值