事故复盘:一次缓存穿透,把数据库打到了 100%

举报
yd_258049613 发表于 2026/11/01 00:26:20 2026/11/01
【摘要】 事故现象: 晚上八点,商品详情接口 P99 从 80ms 涨到 4 秒,数据库 CPU 打满。排查发现大量请求查询一个刚下架的商品 ID,缓存里没有,每次都打到数据库,数据库返回空,也没有回写缓存。请求量本身不大,但每个请求都穿透到 DB,叠加起来把连接池占满。原因拆解: 缓存只缓存了“存在的商品”,不存在的商品不缓存。攻击者或爬虫随便构造 ID,就能绕过缓存。这是典型的缓存穿透。修复措施:...

事故现象: 晚上八点,商品详情接口 P99 从 80ms 涨到 4 秒,数据库 CPU 打满。排查发现大量请求查询一个刚下架的商品 ID,缓存里没有,每次都打到数据库,数据库返回空,也没有回写缓存。请求量本身不大,但每个请求都穿透到 DB,叠加起来把连接池占满。

原因拆解: 缓存只缓存了“存在的商品”,不存在的商品不缓存。攻击者或爬虫随便构造 ID,就能绕过缓存。这是典型的缓存穿透。

修复措施: 第一,对查询结果为空的 key 也缓存一个短 TTL 的空值标记,比如 60 秒。第二,对明显非法的 ID 格式在入口层直接拒绝。第三,热点 key 加互斥锁,避免缓存失效瞬间大量请求同时回源。第四,数据库连接池设等待超时,快速失败而不是无限排队。

更根本的反思: 缓存设计不能只考虑“命中率”,还要考虑“未命中的代价”。穿透、击穿、雪崩是三种不同的失效模式:穿透是查不存在的数据,击穿是热点 key 过期,雪崩是大量 key 同时过期。对应的手段不同,空值缓存、互斥锁、过期时间加随机抖动,别混为一谈。

这次事故的教训不是“加个空值缓存就完了”,而是缓存层要有“防御性设计”。假设流量里一定有异常请求,缓存要能挡住它们,而不是把压力原样传给数据库。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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