缓存穿透、击穿、雪崩:三大经典缓存问题一次讲清

举报
Inarms的日常随记 发表于 2026/11/10 04:18:17 2026/11/10
【摘要】 # T为什么要分清这三个词面试和故障复盘里,"缓存穿透""缓存击穿""缓存雪崩"经常被混着说。它们确实都描述"请求绕过缓存打到数据库",但成因和解法完全不同。用一句话区分:穿透:查的是根本不存在的数据,缓存永远不会有击穿:某个热点 key 恰好过期,瞬间大量请求直击数据库雪崩:大批 key 同时失效(或缓存服务本身宕机),数据库被洪峰冲垮一个查"不存在的用户",一个查"秒杀商品恰好过期",一...

# T

为什么要分清这三个词

面试和故障复盘里,"缓存穿透""缓存击穿""缓存雪崩"经常被混着说。它们确实都描述"请求绕过缓存打到数据库",但成因和解法完全不同。用一句话区分:

  • 穿透:查的是根本不存在的数据,缓存永远不会有
  • 击穿:某个热点 key 恰好过期,瞬间大量请求直击数据库
  • 雪崩:大批 key 同时失效(或缓存服务本身宕机),数据库被洪峰冲垮

一个查"不存在的用户",一个查"秒杀商品恰好过期",一个是"整片缓存集体阵亡"——场景不同,药方也不同。

缓存穿透:查询不存在的数据

成因:请求的参数在数据库里根本没有对应记录(典型如恶意伪造 ID 遍历攻击)。缓存遵循"查不到就不写",于是每次请求都穿透到数据库。数据库本来有空值保护吗?没有——它每次都要执行真实查询并返回空。

解法一:缓存空值

查数据库得到空 → 仍然写入缓存,值为 NULL,设置较短 TTL(如 60 秒)。后续同类请求直接命中空值返回,不再访问数据库。

代价是缓存里存了些无意义条目,配合短 TTL 和参数合法性校验(如 ID 格式、范围检查)可以把垃圾数据压到很低。

解法二:布隆过滤器

在缓存前放一层布隆过滤器:把所有合法 key 预先写入,请求先问过滤器——"这个 key 可能存在吗"。布隆过滤器说"不存在"就一定不存在,直接拦截;说"可能存在"才走缓存和数据库。

特点是空间效率极高(几亿 key 也只需几百 MB),代价是有一定误判率且标准实现不支持删除。适合 key 集合相对稳定的场景。

缓存击穿:单个热点 key 过期

成因:某个被高频访问的 key(如首页爆款商品)到达过期时间的瞬间,成千上万并发请求同时发现缓存失效,全部涌向数据库执行同一个查询。

解法一:互斥锁,只放一个请求去回源

key 失效时:第一个拿到分布式锁(如 SETNX)的请求去查数据库并回填缓存;其他请求短暂自旋等待(如 50ms 重试一次);缓存回填后锁释放,后续请求全部命中缓存。

数据库只承受一次查询压力,代价是等待期间少数请求延迟略增。

解法二:逻辑过期,物理上永不过期

热点 key 不设 TTL,值里额外存一个"逻辑过期时间"。读取时发现逻辑过期,由一个异步线程负责更新缓存,当前请求先返回旧值。优点是完全不阻塞;缺点是短期内部可能返回略旧的数据,适合能容忍短暂不一致的场景。

两种方案选型看业务:一致性敏感选互斥锁,可用性敏感选逻辑过期。

缓存雪崩:大批 key 集体失效

成因:两种典型情况——一是给大量 key 设了相同的 TTL,同一时刻集体过期;二是缓存服务自身宕机,所有请求被迫落到数据库。后者冲击力远大于前两者。

解法一:TTL 加随机偏移

过期时间 = 基础值 + random(0, 300)秒。一行代码把"集体失效"摊薄成"缓慢失效",成本几乎为零,是最应该无条件做的基础防护。

解法二:多级缓存

本地缓存(进程内)作为第一层,分布式缓存作为第二层。分布式缓存抖动时,本地缓存还能顶住一部分读流量,给恢复争取时间。

解法三:缓存服务高可用 + 熔断降级

Redis 用主从 + 哨兵或集群模式避免单点;应用侧对数据库访问加限流熔断——缓存挂了时宁可返回部分旧数据或降级页面,也不能让数据库被洪峰打死。数据库一旦被打挂,恢复时间远长于缓存。

三者对照速查表

问题 触发条件 核心解法 一句话记忆
穿透 数据不存在 空值缓存 / 布隆过滤器 查无此数据
击穿 单个热点 key 过期 互斥锁 / 逻辑过期 精确打击
雪崩 大批 key 同时失效或缓存宕机 TTL 随机化 / 多级缓存 / 熔断降级 全面崩塌

小结

三个问题的本质都是"缓存没有兜住请求",差异只在范围:穿透是数据不存在,击穿是单点过期,雪崩是面状失效。实践中它们常常叠加出现——一次事故里既可能有恶意穿透,也可能恰好赶上批量过期。所以生产系统的标准做法是组合拳:入口做参数校验和布隆过滤器防穿透,热点 key 用逻辑过期防击穿,全局 TTL 随机化加熔断降级防雪崩。缓存体系扛得住异常,数据库才能真正高枕无忧。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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