Redis 缓存穿透、击穿与雪崩:原理与实战解法

举报
yd_255989600 发表于 2026/11/08 20:27:39 2026/11/08
【摘要】 在高并发系统中,缓存几乎成了标配。它用极低的成本挡住了绝大部分读请求,让数据库能够专注于真正需要的写入与热点查询。但缓存并不是银弹,一旦设计不当,反而会把压力成倍地放大到数据库上。其中最常见的三个问题就是缓存穿透、缓存击穿与缓存雪崩。它们的名字很像,成因和解法却完全不同,本文把它们放在一起讲清楚。一、缓存穿透:查一个不存在的数据缓存穿透是指查询一个在缓存和数据库中都不存在的数据。由于数据根本...

在高并发系统中,缓存几乎成了标配。它用极低的成本挡住了绝大部分读请求,让数据库能够专注于真正需要的写入与热点查询。但缓存并不是银弹,一旦设计不当,反而会把压力成倍地放大到数据库上。其中最常见的三个问题就是缓存穿透、缓存击穿与缓存雪崩。它们的名字很像,成因和解法却完全不同,本文把它们放在一起讲清楚。

一、缓存穿透:查一个不存在的数据

缓存穿透是指查询一个在缓存和数据库中都不存在的数据。由于数据根本不存在,缓存永远不会命中,于是每个请求都会穿过缓存直接打到数据库。恶意攻击者如果故意构造大量不存在的 ID 发起请求,数据库就会被无效查询拖垮。

解法主要有两种。第一种是缓存空值:当数据库也查不到时,把一个空结果(比如空字符串或特定标记)写入缓存,并设置一个较短的过期时间,这样同一个不存在的 key 下次就会命中缓存。第二种是布隆过滤器:在缓存之前加一层布隆过滤器,把所有存在的 key 预先写进去,请求先过布隆过滤器,不存在的直接拒绝。布隆过滤器有极小的误判率,但不会漏判,适合数据量大、攻击明显的场景。

二、缓存击穿:热点 key 突然失效

缓存击穿是指某个热点 key 在过期的瞬间,大量并发请求同时涌入,发现缓存为空后一起回源数据库,造成瞬时压力尖峰。它针对的是单个热点 key,和雪崩的“大量 key 同时失效”不同。

经典解法是互斥锁:缓存失效时,只允许一个线程去查询数据库并回填缓存,其他线程等待或返回旧值。在 Redis 中可以用 SETNX 实现分布式锁,拿到锁的线程负责回源,避免数据库被并发打满。另一种思路是逻辑过期:不给 key 设置物理过期时间,而是把过期时间存在 value 里,由后台异步刷新,这样就不存在“过期瞬间”的击穿问题。对于可预知的热点数据,提前预热也是简单有效的办法。

三、缓存雪崩:大量 key 同时失效

缓存雪崩是指在同一时刻大量 key 集中过期,或者 Redis 服务整体不可用,导致请求全部落到数据库,严重时数据库也会被拖垮,形成连锁故障。

应对雪崩的核心是“打散”和“冗余”。给过期时间加一个随机值,让 key 的失效时间分散开,避免集中过期;搭建 Redis 高可用集群(主从加哨兵或 Cluster),避免单点故障导致整个缓存层不可用;再配合多级缓存(本地缓存加分布式缓存)和限流降级手段,即使缓存层出问题,也能把损失控制在可接受范围内。

四、实战中的几点建议

首先,给缓存加上监控,重点关注命中率、慢查询和内存使用,命中率突然下降往往是问题的先兆。其次,对热点 key 做容量规划,避免单 key 过大或过热。最后,任何缓存策略都要经过压测验证,尤其是在大促或活动前,提前发现薄弱点。

缓存穿透、击穿、雪崩虽然表现不同,但本质都是“缓存失效后压力回源”。理解它们的成因,再结合业务特点选择合适的组合方案,才能让缓存真正成为系统的加速器,而不是隐患。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。