缓存穿透、击穿、雪崩:别把三种失效混成一种问题

举报
yd_271358468 发表于 2026/11/07 01:42:06 2026/11/07
【摘要】 系统加了缓存之后变慢,第一反应常常是“缓存没起作用”。但缓存失效有三种完全不同的样子:穿透、击穿、雪崩。它们发生在不同环节、由不同原因触发,解法也不一样。混在一起治,往往是这边补上了,那边又漏了。穿透:请求根本不该进缓存穿透是指查询一个根本不存在的数据,缓存里没有,数据库里也没有,每次请求都会穿过缓存打到数据库。单个请求没什么,怕的是有人用不存在的键批量刷,或者业务逻辑本身就会产生大量空结果...

系统加了缓存之后变慢,第一反应常常是“缓存没起作用”。但缓存失效有三种完全不同的样子:穿透、击穿、雪崩。它们发生在不同环节、由不同原因触发,解法也不一样。混在一起治,往往是这边补上了,那边又漏了。

穿透:请求根本不该进缓存

穿透是指查询一个根本不存在的数据,缓存里没有,数据库里也没有,每次请求都会穿过缓存打到数据库。单个请求没什么,怕的是有人用不存在的键批量刷,或者业务逻辑本身就会产生大量空结果查询,数据库会被这些无意义的查询拖垮。

对付穿透有两个常规办法。一是缓存空结果:查不到时也往缓存里写一个空值,设置一个比较短的过期时间,下次同样的请求直接返回空,不再碰数据库。这个办法简单,但要注意空值和正常值的过期时间分开,空值过期时间要短,否则数据刚写入时,缓存里的空值还会挡住真实数据。

二是请求前先做存在性判断,比如布隆过滤器。布隆过滤器用很小的内存记录“哪些键可能存在”,查询时先过一遍过滤器,不存在的键直接返回,连缓存都不用查。它的代价是有一定的误判率:它说不存在就一定不存在,它说存在却可能并不存在,所以误判时请求还是会走到数据库,但穿透的量已经被大幅削掉。数据量大、空查询多的场景,布隆过滤器比缓存空值更彻底。

击穿:热点键刚好在同一时刻过期

击穿和穿透的区别在于,数据是存在的,只是它的缓存刚好过期了。如果这个键是个热点,过期的一瞬间会有大量并发请求同时发现缓存为空,一起涌向数据库,瞬间把数据库打满。平时缓存好好的,只在过期那几秒出问题,排查时很容易以为是偶发抖动。

最直接的办法是给热点键加互斥锁:第一个发现缓存为空的请求去数据库加载,其他请求等一等,或者直接返回旧值。锁的粒度要控制在单个键上,别把整个缓存操作串行化了。

另一个思路是逻辑过期:缓存里存的数据本身不过期,额外存一个逻辑过期时间戳。读到数据时先判断逻辑时间,过期了就异步刷新、当前请求仍然返回旧数据。这样热点键永远不会出现“同一时刻全部穿透”的窗口,代价是请求可能短暂读到旧数据。读旧数据能不能接受,要看业务:商品详情页的价格可以容忍几秒旧值,库存就不行。

还有一种做法是过期时间加随机抖动:给每个键的过期时间加上几秒到几十秒的随机值,避免大量键在同一时刻集体过期。这招治的是“批量过期”,不是单个热点键,但配合互斥锁效果更好。

雪崩:大量键同时失效

雪崩是击穿的放大版:不是一个键过期,而是一大批键在同一时间过期,或者缓存服务本身挂了,所有请求同时落到数据库。常见诱因有两个,一是上线时批量写入的缓存用了相同的过期时间,到点一起失效;二是缓存集群故障、重启,缓存整体清空。

预防雪崩首先是把过期时间打散。写入时在基础过期时间上加一个随机值,让键的失效时间均匀分布,避免同一时刻集中过期。其次是多级缓存:本地缓存挡一层,分布式缓存挡一层,即使分布式缓存整体失效,本地缓存还能撑住一部分读请求,给系统留出恢复时间。

缓存服务本身也要做高可用。主从、集群、分片都是常规手段,目标是单点故障不至于让整个缓存层消失。更重要的是限流和熔断:当数据库压力超过阈值时,快速拒绝一部分请求,保护数据库不被拖死。雪崩发生时,最怕的不是慢,而是数据库被压垮之后连正常请求也处理不了,限流是最后一道防线。

三种失效的对照

穿透是“查不到的数据被反复查”,根因在请求本身不合法或数据不存在,解法是空值缓存和布隆过滤器。击穿是“热点数据刚好过期”,根因在过期时刻的并发,解法是互斥锁和逻辑过期。雪崩是“大量数据同时失效”,根因在过期时间集中或缓存层整体故障,解法是过期时间打散、多级缓存和高可用加限流。

排查时先看现象再定性:是不是只有不存在的键在慢,是穿透;是不是只在某个整点或某个键过期时抖一下,是击穿;是不是所有请求同时变慢、数据库连接数瞬间打满,是雪崩。现象对上了,解法才不会用错地方。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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