首页推荐缓存统一设了三千六百秒过期,整点刷新后一秒内几十万个 key 同时失效,数据库连接数瞬间打满,接口大面积五零四,Redis 是单节点。

一开始怀疑是「没有多级缓存,失效后回源全部打到数据库」,查了一圈,方向不对。

这类报错背后常见的原因有几处,逐个排除就行。过期时间用了固定值,没加随机偏移。少数情况下是整批缓存是同时预热写入的,到期时间天然一致。

另外,热点数据没有永不过期的兜底副本。

上来先找出集中过期的那批 key

redis-cli --scan --pattern 'rec:*' | head -20

接着看剩余存活时间是否高度一致

redis-cli ttl rec:home:1001

给过期时间加随机抖动并重置

redis-cli set rec:home:1001 '{}' EX 3900

回源加并发控制限制重建线程数

redis-cli info commandstats | grep -E 'get|set'

别只看报错消失,验证要多做一步。整点过后数据库 QPS 曲线平滑没有尖峰,命中率始终在九成以上,接口不再出现批量五零四。

容易忽略的是,雪崩和击穿的区别在失效范围,前者是一大片后者是单点;过期时间加三百秒以内的随机量是最省事的做法。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。

作者 9823189