网易首页 > 网易号 > 正文 申请入驻

双十一零点崩溃?三招拆解Redis缓存连环劫

0
分享至

凌晨两点,运维群里突然炸锅——数据库连接数飙到2000+,服务响应从50ms跌到15秒。你盯着监控大屏,看着"系统繁忙"的报错像潮水一样涌来,却不知道敌人从哪来。这不是什么神秘攻击,而是Redis缓存的三道裂缝被同时撕开:有人用脚本狂刷不存在的用户ID,爆款商品缓存刚好过期,整库Key又集体失效。三股力量拧成一股绳,把数据库勒到窒息。

今天我们把这三道裂缝摊开来看:穿透、击穿、雪崩。不是背定义,而是看它们怎么联手搞垮一个系统,以及怎么用三行代码守住防线。


第一道裂缝:穿透——"查无此人"的无限循环

穿透的逻辑很刁钻。攻击者(或Bug)反复查询根本不存在的数据,比如user:999999999。缓存里没有,请求直扑数据库,高频无效查询把DB打成筛子。

原文给了一个触目惊心的场景:「EXISTS user:999999999 返回0,但每秒1万次?DB瞬间变筛子。」

这里有个反直觉的点——缓存对"不存在"是无能为力的。它只能记住"存在过什么",却记不住"什么不存在"。攻击者就是利用这个盲区,用海量不存在的Key把数据库的查询队列塞爆。

防御需要双保险。第一重是存在性前置校验,用布隆过滤器(Bloom Filter)在缓存之前拦一道。布隆过滤器是一种概率型数据结构,能告诉你"这个Key绝对不存在"或"可能存在"。把全量用户ID哈希进去,查询时先过一遍,绝对没有的直接返回None,连Redis都不用碰。

第二重是空值短期缓存。万一布隆过滤器误判(概率极低但存在),或者业务上确实需要查库确认,就把"查无此人"的结果也缓存起来——但只存5分钟。这样同一个无效ID短期内不会反复击穿。

原文的Python示例很清晰:先查布隆过滤器,再查Redis,最后才碰数据库;数据库返回空也写缓存,TTL设300秒。核心就两点:存在性前置校验 + 空值短期缓存,把无效流量挡在数据库门外。

这里有个真实战损案例。原文提到:「我们曾在线上活动遭遇穿透事故:未对注册手机号做空值缓存,黑产脚本遍历user:138****0001~138****9999,DB连接数10秒飙至2000+,服务全面超时。」

黑产脚本的思路很简单:批量遍历手机号段,看哪些是注册过的。如果没做防护,每一次遍历都是一次数据库查询。10秒2000+连接,意味着每秒200次无效查询——对大多数MySQL实例来说,这已经是死刑。

第二道裂缝:击穿——热点Key的"死亡毫秒"

击穿比穿透更隐蔽,因为它发生在"正常业务"里。某个超高频Key(比如首页推荐位hot_item)恰好过期,瞬间大量并发请求穿透缓存,争抢重建,数据库CPU飙升。

原文描述了这个惊险的刹那:「GET hot_item 返回 nil 的刹那,1000个线程同时执行SET——谁先写?谁来查库?没协调就是灾难。」

想象一下:缓存里存着爆款商品的详情,每秒被访问上万次。TTL走到尽头,Redis把Key删掉。第一个请求发现没有,去查数据库;但第二个、第一百个、第一千个请求也在同一毫秒到达,它们都看到nil,都决定去查数据库。数据库瞬间被1000个相同查询压垮,而缓存重建完成后,大部分查询都是浪费的。

这就是击穿的本质:缓存失效的瞬间,并发流量没有"刹车",集体涌向数据库。

解决方案是加锁重建,但锁的设计有很多陷阱。原文给出了一个完整的Python实现,值得逐行拆解:

首先,尝试获取分布式锁,用Redis的SETNX(Set if Not Exists)命令,带5秒自动过期——这是为了防止进程崩溃导致死锁。抢到锁之后,必须做二次检查:因为拿到锁和开始重建之间可能有时间差,别的进程可能已经重建好了。如果缓存已有数据,直接返回,避免重复查询。

重建完成后,设置3600秒的TTL,然后在finally块里释放锁——无论成功与否,锁必须释放,这是铁律。

没抢到锁的进程呢?短暂休眠10毫秒后重试,或者直接返回降级数据(比如旧缓存或静态兜底)。原文强调:「关键点:锁粒度最小化、自动过期、二次检查、异常必释放。」

这里有个常见的反模式:有人用全局锁保护所有缓存重建,结果热点Key没击穿,非热点Key却被串行化拖慢。锁的粒度必须是Key级别的,一个商品的锁不能挡住另一个商品。

第三道裂缝:雪崩——缓存的"集体休眠"

雪崩是击穿的批量版。大量Key设置相同过期时间(比如凌晨2点统一TTL=3600),到期后集中失效,流量洪峰同步涌向数据库。

原文给了一个危险操作:「KEYS item:* 生产禁用!」KEYS命令会遍历全库,在Key多的实例上直接卡死。更安全的做法是SCAN配合TTL采样,渐进式检查。

雪崩的根源是"人为制造的同步"。很多团队为了管理方便,给一批数据设置相同的过期时间,或者批量重启缓存服务后统一刷新。这就像让所有员工同时去食堂吃饭——窗口再多也会挤爆。

根治方案是两招并用。第一招是随机抖动(Jitter):基础TTL上下浮动10%,让过期时间分散开。原文的Python示例里,3600秒的TTL会变成3240~3960秒之间的随机值,Key们不再整齐划一地消失。

第二招是逻辑永不过期:核心数据不设TTL,靠后台任务异步刷新。原文的代码里,set_essential_item只执行SET不执行SETEX,然后每30分钟主动更新一次。这样缓存永远不会"空窗",数据库永远有缓冲层。

口诀记牢:「不设固定过期时间,只设'基础TTL+随机抖动';核心数据宁可冗余更新,也不集体断供。」

这里有个成本权衡。逻辑永不过期意味着缓存和数据库可能短暂不一致(最多30分钟),以及额外的刷新任务开销。但对于首页推荐、用户基础信息这类读多写少、一致性容忍度高的场景,这是值得的。

三道裂缝,一套心法

穿透、击穿、雪崩,表面是三个独立问题,底层是同一道裂缝:缓存与数据源之间的"空窗期"被恶意或意外地放大。

穿透放大的是"查询不存在"的空窗——缓存不会记住不存在的东西,需要外部机制补位。击穿放大的是"重建中"的空窗——一个Key的失效被并发请求乘数放大。雪崩放大的是"批量失效"的空窗——时间上的同步变成流量上的洪峰。

守住它们,原文总结了三招:

存在性校验——布隆过滤器+空值缓存,让"不存在"止步于缓存层;

热点保护——原子锁+双重检查,把重建动作串行化;

过期分散——随机TTL+异步刷新,避免缓存集体休眠。

这三招不是互斥的,而是叠加的。一个完善的缓存系统,可能同时用上布隆过滤器拦截穿透、分布式锁保护热点Key、随机抖动防止雪崩,再加上异步任务兜底核心数据。

原文最后抛了一个开放问题:「你在项目中用过哪种防护组合?欢迎在评论区晒出你的redis.conf关键配置或自研工具片段——Dev.to的极客们,正等着抄作业呢!」

监控不是锦上添花,而是故障前的最后一道哨兵。原文的这句提醒,放在任何防御方案之后都不过时。布隆过滤器的误判率、锁的等待超时、缓存命中率的趋势——这些指标应该在Dashboard上实时跳动,而不是等到DB连接数飙到2000才后知后觉。

缓存不是银弹,而是需要精心设计的防护体系。它不会自动解决性能问题,只会把性能问题的爆炸点从数据库转移到缓存层——如果设计不当,爆炸会更剧烈。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
51岁林志玲自曝为和公婆住一起换大房子!回中国发展后越变越美

51岁林志玲自曝为和公婆住一起换大房子!回中国发展后越变越美

明星私服穿搭daily
2026-04-28 13:57:03
竞拍者叫价6003万元抢到深圳高端别墅后悔拍,758万元保证金打水漂,竞拍时曾一次性加价达2211万元,拍卖方回应

竞拍者叫价6003万元抢到深圳高端别墅后悔拍,758万元保证金打水漂,竞拍时曾一次性加价达2211万元,拍卖方回应

极目新闻
2026-04-29 12:45:06
掘金落后晋级概率却达55% 约基奇最佳一战改心态 第三次1-3逆转?

掘金落后晋级概率却达55% 约基奇最佳一战改心态 第三次1-3逆转?

颜小白的篮球梦
2026-04-29 06:56:42
“不想浪费长假”,男子5天连做5台手术!本人最新回应:非常难受,已老实,千万别学我

“不想浪费长假”,男子5天连做5台手术!本人最新回应:非常难受,已老实,千万别学我

封面新闻
2026-04-29 13:08:06
特朗普抨击默茨关于美以伊战事言论

特朗普抨击默茨关于美以伊战事言论

参考消息
2026-04-29 14:27:06
迪瓦茨为何当初不选东契奇? 给出的两条理由如今匪夷所思

迪瓦茨为何当初不选东契奇? 给出的两条理由如今匪夷所思

仰卧撑FTUer
2026-04-29 09:57:03
阿联酋增产并绕过霍尔木兹海峡出口石油,美国将长期封锁伊朗

阿联酋增产并绕过霍尔木兹海峡出口石油,美国将长期封锁伊朗

山河路口
2026-04-29 13:06:10
突发!40岁重返NBA?联手胖虎?盼了这么多年,终于来了...

突发!40岁重返NBA?联手胖虎?盼了这么多年,终于来了...

左右为篮
2026-04-29 12:43:52
如今隐居上海的黄梅莹,和儿子彻底划清界限后,75岁越活越潇洒

如今隐居上海的黄梅莹,和儿子彻底划清界限后,75岁越活越潇洒

青橘罐头
2026-04-15 14:54:15
“不给6套房加1个亿,不搬”,钉子户张新国坚守14年,终败给现实

“不给6套房加1个亿,不搬”,钉子户张新国坚守14年,终败给现实

红梦史说
2025-07-11 11:23:39
中国职业拳击又遭重创!拳手到非洲比赛被下药,全军覆没!

中国职业拳击又遭重创!拳手到非洲比赛被下药,全军覆没!

拳击时空
2026-04-29 06:29:08
火箭最应该送走的五人!杜兰特不适合留下,解雇乌度卡救全队

火箭最应该送走的五人!杜兰特不适合留下,解雇乌度卡救全队

余憁搞笑段子
2026-04-29 14:45:51
西方为何不敢招惹中国?只因中越712炮战,我军1天发射3400吨炮弹

西方为何不敢招惹中国?只因中越712炮战,我军1天发射3400吨炮弹

鹤羽说个事
2026-04-25 22:19:50
内马尔:我真的很想去踢世界杯;希望在世界杯决赛和梅西交手

内马尔:我真的很想去踢世界杯;希望在世界杯决赛和梅西交手

懂球帝
2026-04-29 14:33:20
ESPN预测湖人火箭G5胜率:湖人50.5%,火箭49.5%

ESPN预测湖人火箭G5胜率:湖人50.5%,火箭49.5%

懂球帝
2026-04-29 16:34:22
这身材相貌绝对旺夫,大家有何看法

这身材相貌绝对旺夫,大家有何看法

动物奇奇怪怪
2026-04-29 14:23:49
美军最强钻地弹被缴获,伊朗拆开后马上决定:不用中俄帮,直接抄

美军最强钻地弹被缴获,伊朗拆开后马上决定:不用中俄帮,直接抄

影孖看世界
2026-04-28 21:11:27
特斯拉新款Model Y大更新,细节改得是真良心

特斯拉新款Model Y大更新,细节改得是真良心

华庭讲美食
2026-04-29 10:54:42
罗马诺:皇马15天前就得知穆里尼奥可以回归

罗马诺:皇马15天前就得知穆里尼奥可以回归

懂球帝
2026-04-28 23:17:24
这是不是欧冠历史最伟大的半决赛?说出你的选择!

这是不是欧冠历史最伟大的半决赛?说出你的选择!

懂个球
2026-04-29 16:19:25
2026-04-29 16:51:00
像素与芯片
像素与芯片
有态度网友ytd
2949文章数 19关注度
往期回顾 全部

科技要闻

今晨庭审纪实|马斯克当庭讲述OpenAI被偷走

头条要闻

孙杨方回应"孙杨妈妈要求删除马頔发言":毫无事实依据

头条要闻

孙杨方回应"孙杨妈妈要求删除马頔发言":毫无事实依据

体育要闻

一场九球狂欢,各路神仙批量下凡

娱乐要闻

马頔一句话,孙杨妈妈怒骂节目组2小时

财经要闻

曾经的新能源首富,希望又破了!

汽车要闻

配32寸升降屏 新款别克世纪CENTURY上市53.99万起

态度原创

教育
手机
健康
公开课
军事航空

教育要闻

海淀标杆校“天花板”来了!这所学校再迎高光时刻

手机要闻

华为Mate X5、nova 14等机型鸿蒙HarmonyOS 6.1系统“转正”

干细胞治烧烫伤能用了么?

公开课

李玫瑾:为什么性格比能力更重要?

军事要闻

美国参议院否决限制特朗普对古巴动武的决议

无障碍浏览 进入关怀版