每天 00:00 报表缓存集体失效,20 个定时任务同时查库,数据库 CPU 从 30% 冲到 100%,持续 90 秒。乍看像缓存或者权限的锅,追下去往往不是。

SET report:daily EX 3600 NX
SET report:daily EX 3660

追下去是这么回事:所有报表的缓存 TTL 都设成到次日零点,过期时间完全重合。失效瞬间没有互斥,每个请求都自己去查库。报表查询本身要扫几千万行,20 个并发直接把连接池占满。

碰到「报表缓存击穿」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。

具体做法是,TTL 加随机偏移 打散过期时间;缓存失效时用分布式锁 只放一个请求回源;回源期间其他请求返回旧值 不阻塞;在 00:00 观察数据库 CPU 和回源次数。

验收就看一点,00:00 数据库 CPU 峰值降到 45%,同一报表只回源一次。

作者 9823189