Redis缓存穿透到底是咋回事,怎么理解这个问题其实没那么简单
- 问答
- 2026-01-25 23:24:59
- 6
Redis缓存穿透这个问题,很多人一听就觉得“不就是查不到数据嘛”,但它的复杂性和破坏力,其实远超表面理解,咱们一步步拆开说。
最直白的理解是:有人拼命请求一个根本不存在的数据,比如你的数据库里用户ID是从1到10000,有人却一直用-1或者99999这样的ID来查询,因为数据不存在,Redis里自然没有缓存(这被称为“缓存未命中”),请求就会每次都直接砸到后面的数据库上,如果短时间内有大量这样的恶意请求,数据库就可能扛不住,直接挂掉,导致整个服务瘫痪,这是最基础的一层。
但问题没那么简单,第一层复杂在于,“不存在”这个状态本身是很难被记住的,一个正常的思路是:第一次查询数据库发现没有,那我就在Redis里缓存一个“空值”(比如NULL),并设置一个较短的过期时间,这样后续同样的请求在过期前就能被Redis挡住,不会再去查数据库,这个方案很常见,很多资料(比如早期技术博客和《Redis实战》这类书籍的讨论中)都会提到,漏洞就在这里:如果攻击者每次请求都变换不同的、根本不存在的Key呢?比如他拿一堆随机生成的用户ID来撞你的系统,你缓存了“空值”,但他下一次用的又是另一个新ID,你的“空值缓存”策略就完全失效了,数据库依然要面对海量不重复的无效查询,这就引出了第二个关键点:穿透的本质是“绕过缓存”的、对数据库的随机Key攻击。
这就带出了更深入的思考:如何判断一个Key在系统中“可能存在”还是“绝对不存在”?一个叫 布隆过滤器(Bloom Filter) 的工具被引入了讨论(在《Redis深度历险》等资料中有重点阐述),你可以把它想象成一个放在Redis前面的、很高效的“初步筛查员”,它用很小的内存代价,能快速告诉你:“这个Key肯定不存在”或者“这个Key可能存在”,如果它说“肯定不存在”,那请求就可以直接被打回去,连缓存和数据库都不用碰了,这听起来是终极解决方案,对吧?
但这就是问题第三层复杂的地方:布隆过滤器并不是万能的,它需要预热,也就是必须把系统里所有可能存在的Key(比如所有有效的用户ID)提前加载进去,这对于海量数据或动态生成的数据来说,有时是个挑战,它存在一定的误判率(它说“可能存在”时,有极小的概率其实是“不存在”),这意味着可能会有少量无效请求依然会穿透到缓存层,它增加了系统的架构复杂度和维护成本,是否引入布隆过滤器,是一个需要权衡技术成本、业务场景和安全风险的架构决策。
缓存穿透的“杀伤力”还和业务场景强相关,在一些核心业务路径上(比如查询商品信息、用户基础信息),一旦发生穿透,影响是致命的,而在一些非核心的查询场景,可能影响就小很多,它常常和缓存击穿(某个热点Key过期瞬间的大量请求)、缓存雪崩(大量Key同时过期)等问题被一起讨论和混淆,但它们的成因和解决方案侧重点各有不同。
理解Redis缓存穿透,不能停留在“缓存空对象”这一步,它本质上是一个系统边界防御和数据存在性判断的难题,从一个简单的“查不到数据”现象出发,会牵扯出恶意攻击的模式识别、缓存策略的设计缺陷、高效数据结构(如布隆过滤器)的适用性与代价,以及不同业务场景下的风险等级评估等一系列环环相扣的问题,它考验的是开发者对数据流动路径的全面把控能力,以及根据实际情况在简单方案与复杂架构之间做出合理取舍的能力,这才是它“没那么简单”的真正原因。

本文由黎家于2026-01-25发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://tgpc.haoid.cn/wenda/85951.html