缓存穿透、击穿和雪崩分别是什么,如何治理?

考查重点:缓存故障类型与回源保护。穿透查不存在数据,用校验/空值/布隆过滤;击穿是热点过期,用互斥回源;雪崩是大批失效,用错峰和限流

本题目录

参考答案

核心回答

三者都会让过多请求绕过缓存、增加数据库压力,区别在于数据是否存在,以及失效集中在一个热点还是大片缓存。

  • 缓存穿透:请求的数据在缓存和数据库中都不存在,反复查询仍无法填充正常缓存。先校验参数、限制异常请求,再对查无结果设置短期空值缓存;不存在的 ID 很分散时,可用布隆过滤器提前过滤。
  • 缓存击穿:数据库中有数据,但某个热点 key 过期、被淘汰或尚未建立,大量请求同时回源重建。可以提前预热、合并同一 key 的重建请求,或用互斥锁限制重建;允许短暂旧数据时,可采用逻辑过期、异步刷新。
  • 缓存雪崩:大量 key 集中失效,或者缓存服务整体不可用,导致大范围回源。集中过期用随机 TTL、分批预热来打散;服务故障则依靠高可用、快速超时、限流和降级。无论哪种情况,都要限制回源总量,避免把缓存故障扩大成数据库故障。

下面用取货场景对比三种故障:货架表示缓存,仓库表示数据库。看请求的编号、两处是否有对应数据,以及回源范围,就能区分穿透、击穿和雪崩;每幅场景下方列出常见处理方法。

缓存取货场景:两处都无数据的穿透、单个热点缓存缺失的击穿、大片缓存失效的雪崩,以及对应处理方法

穿透:空值缓存和布隆过滤器如何配合?

以查询商品为例,数据库确认商品不存在后,缓存一个明确的“无此商品”标记,并设置较短 TTL。后续相同 ID 可直接返回不存在,程序要能区分这个标记与“缓存未命中”。TTL 太长会延迟新商品被读到,因此创建数据后还应删除或更新对应空值缓存。

空值缓存适合重复查询相同不存在 ID 的情况。若请求不断更换 ID,它既挡不住第一次回源,还会占用缓存空间。这时可用布隆过滤器记录有效 ID:有效 ID 已完整加入过滤器时,返回“不存在”的请求可以拦截;返回“可能存在”仍需继续查询。 它可能误放行不存在的 ID,不能保证数据库完全没有穿透流量。

“没有假阴性”针对已经加入且未被破坏的过滤器集合。新增商品若尚未同步到过滤器,直接据此拒绝就会误拦真实数据;因此要处理增量同步、重建切换和过滤器不可用时的策略。普通过滤器也不适合直接清除某个元素对应的位,因为这些位可能被其他元素共享。

数据库超时与查无结果也要区分。超时只能说明本次查询失败,不能把它缓存成“商品不存在”。

击穿:互斥重建和逻辑过期怎样选?

互斥重建适合希望拿到新数据、能够接受短暂等待的场景。缓存未命中后,只有获得该 key 重建资格的请求回源;拿到锁后再查一次缓存,避免重复重建。其他请求有限等待后重新读缓存,或按业务返回旧值、降级结果,不能抢锁失败就全部转向数据库。

本地锁只能合并当前进程内的请求,多实例部署时每个实例仍可能各自重建。若要跨实例合并,需要分布式协调。采用 Redis 锁时,应原子地设置锁与租约,使用独立持有者标识并按标识原子释放;锁租约过期、任务超时和故障切换仍可能带来并发重建,需要配合超时、续租或版本检查。这里的目标是控制回源量,不能只加一把锁就假定所有故障下都只重建一次。

逻辑过期把刷新时间放在缓存值中,数据到期后仍可读取,由一个受控后台任务刷新,其他请求暂时使用旧数据。它减少等待,但允许短暂不一致,适合商品介绍、榜单等可容忍陈旧的内容;库存扣减、权限校验等关键决策不适合直接依赖过期值。还要设置可接受的最大陈旧时间,处理刷新失败,以及缓存被淘汰或首次没有旧值时的受控回源。

雪崩:集中过期与缓存故障要分别处理

大量 key 集中过期时,可以在满足业务时效要求的范围内给 TTL 加随机偏移,分散预热和刷新批次,同时限制重建并发。每个 key 只重建一次,也可能有成千上万个 key 一起重建,因此还需要数据库层面的总回源预算。

Redis 故障时,随机 TTL 无法发挥作用。应用应快速识别超时或连接失败,避免请求长时间占住线程和连接;通过熔断减少持续失败的调用,再结合本地旧缓存、受控回源或明确降级维持必要功能。高可用部署能缩短故障影响,但切换仍可能有窗口,不能按“缓存永远可用”设计。恢复时分批预热、逐步放开流量,避免冷缓存再次冲击数据库。

排查可先看缓存错误率和延迟,再看未命中是否集中在少数热点、是否出现大量不同的不存在 ID,以及过期量、淘汰量和数据库回源 QPS 的变化。对应修复后,还应检查回源并发、数据库延迟和接口成功率是否恢复。

常见追问

热点 key 永不过期就能解决击穿吗? 只能避免 TTL 到期这一个原因。数据仍可能被淘汰、误删除或随缓存故障丢失;数据更新也需要刷新机制。应保留预热、重建与回源保护。

逻辑过期一定比互斥锁一致性更好吗? 不一定。逻辑过期主动允许读取旧值,优势在于减少等待;互斥重建、后台刷新也可以结合使用。选型依据是业务允许多旧的数据、能等多久,以及回源成本。

参考资料

相关面经

35 篇

多益网络

软件开发工程师
一面
查看原面经 →
Redis 你也用到过,对吧?使用 Redis 缓存会存在什么问题?
追问
怎么避免这些问题?

启云方

AI 应用开发工程师
一面
查看原面经 →
Redis 缓存击穿是什么?怎么解决?

字节跳动

后端开发
日常实习一面、二面
查看原面经 →
讲下高并发场景下有哪些缓存问题,怎么解决

腾讯音乐

后端开发工程师
秋招一面
查看原面经 →
分别说明缓存穿透、击穿、雪崩及其解决方案

水滴公司

AI 全栈工程师
校招秋招一面、二面
查看原面经 →
回到 Redis,常说的缓存击穿、穿透、雪崩,展开讲一讲。
展开剩余 30 篇面经

网易云音乐

全栈开发 / 后端开发实习
实习秋招一面
查看原面经 →
缓存穿透、击穿、雪崩是什么?怎么处理?
缓存击穿还有哪些处理方式?(加锁、永不过期、拆分打散、预热)

水滴

AI全栈
校招一面
查看原面经 →
Redis 缓存穿透、缓存击穿和缓存雪崩分别是什么?
如何解决缓存击穿?
如何解决缓存雪崩?

极智嘉

机器人仿真岗位
查看原面经 →
大量缓存同时失效并导致请求打到数据库时,应如何处理?

公司未注明

测试开发岗
一面、二面、三面
查看原面经 →
Redis缓存高频问答,缓存key怎么设计,缓存失效策略,如何处理缓存击穿、穿透、雪崩。

小红书

面经合集
查看原面经 →
Tlllllllll(读者,自己的面试经历):我都不知道我面了有什么意义,问了巨简单的八股缓存击穿啥的,面完直接结束流程,我都不知道为啥

快手

测试开发
一面
查看原面经 →
redis知道吗,讲讲你熟悉的(三大缓存、主从复制AOF RDB区别)

阿里巴巴

AI Agent 算法
一面
查看原面经 →
**面试官:** 缓存击穿、缓存穿透、缓存雪崩是什么?怎么解决?

顺丰

后端开发工程师
一面
查看原面经 →
缓存三剑客

恒生电子

AI 开发工程师
校招秋招
查看原面经 →
分别说明缓存穿透、缓存击穿、缓存雪崩是什么,对应的解决方案有哪些?

美团

AI 全栈开发工程师
校招秋招二面
查看原面经 →
缓存穿透、缓存击穿、缓存雪崩区别是什么?分别怎么解决

阿里巴巴

AI 应用研发工程师
校招秋招一面
查看原面经 →
Redis缓存击穿、穿透、雪崩分别怎么解决

百度

后端开发工程师
一面
查看原面经 →
缓存三兄弟。

蚂蚁集团

面经合集
查看原面经 →
解释一下 Redis 中的缓存穿透、缓存击穿、缓存雪崩

字节跳动

Agent 开发工程师
一面
查看原面经 →
如果大量 key 同时过期,缓存击穿数据库,该怎么处理?

作业帮

Agent 应用开发工程师
秋招一面
查看原面经 →
讲一讲缓存雪崩、缓存击穿、缓存穿透三者的区别以及对应的应对方案。

知乎

全栈开发工程师
秋招一面
查看原面经 →
redis三大问题和解决方法

车300

Java 开发工程师
实习
查看原面经 →
删除缓存后大量请求打到数据库怎么办(缓存击穿)?

字节跳动

AI 全栈开发工程师
秋招一面
查看原面经 →
缓存三剑客

蚂蚁集团

Agent 开发工程师
秋招一面
查看原面经 →
Redis中缓存穿透、缓存击穿、缓存雪崩分别是什么?对应有哪些解决方案?

字节跳动

Agent 开发工程师
秋招一面
查看原面经 →
了解过Redis吗?缓存击穿、缓存穿透、缓存雪崩三兄弟是什么,如何解决?

小红书

全栈开发
社招一面
查看原面经 →
缓存雪崩问题解决

浦发银行

AI 开发
社招一面
查看原面经 →
缓存击穿、雪崩、穿透如何解决

滴滴

国际化后端开发
社招一面、二面、三面
查看原面经 →
缓存一致性问题、穿透、雪崩的方案

禅游科技

全栈开发工程师
实习一面
查看原面经 →
缓存三剑客

阿里巴巴

后端开发
日常实习一面
查看原面经 →
缓存穿透、缓存击穿、缓存雪崩分别是什么?怎么解决?

法大大

Java 开发工程师
实习一面
查看原面经 →
我看你博客写了缓存穿透和缓存击穿,解释一下
哪个是数据库没数据
缓存穿透和缓存击穿的解决方式

阿里巴巴

后端开发工程师(AI)
实习一面
查看原面经 →
缓存穿透、缓存击穿、缓存雪崩分别是什么? 怎么解决?

腾讯

后端开发工程师(AI)
实习
查看原面经 →
如何避免缓存雪崩、击穿、穿透?

滴滴

Agent 开发工程师
日常实习
查看原面经 →
Redis三剑客

字节跳动

后端开发工程师(AI / Agent 方向)
四面
查看原面经 →
redis缓存三剑客

收录题集

2 个来源,共2 份题集

相关题目

4 题