Redis缓存那些坑,雪崩击穿穿透到底咋回事儿?
- 问答
- 2026-01-19 16:13:12
- 1
综合参考自知乎技术社区高赞回答“缓存常见的坑”、掘金小册《Redis深度历险》以及博客园多位技术博主的经验总结)
咱们现在都用Redis来给数据库做缓存,目的很简单,就是让系统跑得更快,别让数据库压力太大,但用不好缓存,那可就不是加速器,而是捣蛋鬼了,最著名的三个“坑”就是缓存雪崩、缓存击穿和缓存穿透,听名字挺吓人,其实道理不难懂,我一个个给你说。
第一个大坑:缓存雪崩
你想啊,缓存里通常放着很多数据,每条数据都会设置一个过期时间,假设一个极端情况:在同一时刻,缓存里大量的数据集体过期了,或者更倒霉,Redis缓存服务器本身突然宕机了,整个缓存层几乎瘫痪,这时候会发生什么?

大量的用户请求,原本可以直接从缓存里轻松拿到结果,现在发现缓存里没数据了(缓存失效或缓存没了),那这些请求会干嘛?它们会齐刷刷地、像洪水一样直接冲向后端的数据库(比如MySQL),数据库的连接数是有限的,它哪能承受得住这种瞬间的巨量查询请求?结果就是数据库的连接被迅速占满,CPU和内存飙升,处理速度急剧下降,甚至直接崩溃掉线,这样一来,整个系统就无法对外提供服务了,就像雪山崩塌一样,连锁反应,一发不可收拾,所以叫“雪崩”。
(参考知乎回答“如何防止缓存雪崩?”中的比喻)这就好比一个热门景区,平时游客都先在广场(缓存)排队领导览图,突然广场的管理系统瘫痪了,所有游客只能涌向唯一的小售票窗口(数据库),窗口瞬间就被挤爆了。
那怎么解决呢?有几个常见的招:

- 错开过期时间:别让所有缓存的过期时间都一样,在设置过期时间时,加上一个随机数,让它们在相近的时间段内陆续过期,避免集体失效。
- 搭建高可用缓存集群:用一个Redis可能挂掉,那就用Redis集群(比如哨兵模式、集群模式),这样即使一台机器宕机,其他的还能顶上来,保证服务不中断。
- “提前续命”:对于一些热点key,可以设置逻辑过期时间,而不是物理过期,即使数据还在缓存里,程序会判断它是否逻辑上“过期”了,如果过期,就主动去更新它,这样可以避免用户请求时才发现过期。
- 服务降级与熔断:在系统检测到数据库压力过大时,可以暂时关闭一些非核心的功能,或者直接给用户返回一个友好的提示(如“系统繁忙,请稍后再试”),保护数据库不被压垮。
第二个坑:缓存击穿
击穿和雪崩有点像,但破坏范围小一些,可以理解为“定点爆破”,它指的是某一个非常热点的数据(比如某个顶流明星的新闻详情)在缓存中过期了,就在它过期的这个时间点,有海量的请求同时来访问这个特定的数据,这时候,缓存里没有,所有这些请求就会全部打到数据库上,去查询这同一条记录,数据库瞬间承受巨大的压力,可能因此被拖慢,甚至影响其他查询。
(参考掘金小册《Redis深度历险》中的描述)缓存击穿就像是雪崩的一个特例,雪崩是很多key同时失效,而击穿是一个价值连城的key失效,被万箭穿心。

解决办法主要针对这个“热点key”:
- 设置永不过期:对于一些极热点的key,可以直接设置为永不过期,然后由后台任务或者程序在数据变更时主动去更新缓存。
- 加互斥锁:这是最常用的方法,当第一个发现缓存失效的请求到来时,它先去获得一个分布式锁,然后由它一个人去数据库查询数据并重建缓存,在这个过程中,其他请求要么等待,要么直接返回默认值,等缓存重建好后,后续请求就能直接从缓存中获取数据了,这样就避免了大量请求同时去查数据库。
第三个坑:缓存穿透
穿透这个最气人,它指的是用户请求的数据,在缓存中和数据库中根本都不存在!比如请求一个不存在的用户ID或者商品ID,每次针对这个不存在key的请求,缓存里肯定没有(因为不存在),所以一定会去查数据库,数据库也查不到,自然也就无法写入缓存,这样一来,每次请求都会穿透缓存,直接访问数据库,如果有人恶意攻击,构造大量根本不存在的key来请求你的系统,数据库很快就会被这些无意义的查询拖垮。
(参考博客园博文“聊聊缓存穿透与布隆过滤器”)这就像你家里有个防盗门(缓存),但坏人专门找墙上不存在的门(不存在的数据)往里撞,每次都直接撞到承重墙(数据库)上。
解决方案:
- 参数校验:在API层做严格的参数校验,比如ID必须是正数、符合一定规则等,把一些明显非法的请求直接挡在外面。
- 缓存空对象:即使数据库查不到,也在缓存里给这个key设置一个空值(比如
null)并设置一个较短的过期时间,这样后续同样的请求过来,在缓存层就返回空了,不会再到数据库,但要注意,如果攻击者每次都用不同的随机key,这个方法效果会打折扣。 - 使用布隆过滤器:这是一个非常高效的解决方案,布隆过滤器可以告诉你“某个元素一定不存在”或者“可能存在”于一个集合中,在访问缓存之前,先让请求经过布隆过滤器这一关,如果过滤器说这个key不存在,那就可以直接返回,不用再查缓存和数据库了,只有过滤器说可能存在,才继续后续流程,这样可以拦截掉绝大部分恶意的不存在key的请求。
这三个坑都是因为缓存没能有效地保护数据库导致的,雪崩是大量数据失效,击穿是热点数据失效,穿透是查询不存在的数据,理解了它们的原因,再对症下药,就能让缓存系统真正成为你的得力助手。
本文由凤伟才于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/83760.html