缓存事故演练 / Cache stampede
一个 key 过期,为什么能拖垮商品库?
所有请求都命中了同一个热点接口。缓存刚好失效时,区别不在 Redis miss 本身,而在于随后究竟有多少请求同时拿着同一条 SQL 去抢数据库连接。
个
同一热点商品在 key 失效后收到的并发读取
ms
模拟 SELECT … FROM products WHERE sku = ?
条
无保护时,请求会在这里争抢连接
等待选择一种模式
DB 0等待 0超时 0
并发请求
Node.js
Redis miss
key expired
连接池
排队取连接
商品数据库
products
响应 / 超时
1,000 ms
轨迹中的圆点是并发请求的代表样本;面板统计使用完整请求数。
两次运行的账单
P95 / P99 为客户端观察值,超过 1,000 ms 记为超时。
指标
无保护
互斥回填
数据库查询
未运行
未运行
服务端收尾
—
—
排队请求
—
—
客户端超时
—
—
P95 / P99
—
—
“排队请求”在无保护模式中指等待数据库连接,在互斥模式中指等待首个请求完成回填。真实系统还应给锁设置短 TTL,并在等待后重新读取 Redis,避免锁持有者异常退出造成永久阻塞。