游戏卡顿白皮书 › L12 数据库
缓存雪崩 Cache stampede / thundering herd
原因 ID db-cache-stampede · 主责 研发团队·服务器开发 · 配合 运维团队·数据库运维
在含图示和实验的完整版中打开此卡片 →
热门数据的缓存同时过期时,几千个请求会一下子涌向 DB。
起因 存在 Redis 等处的热门数据同时过期 → 结果 想重新生成同一份数据的请求一起涌向 DB → 画面表现 DB 过载,多个功能接连变慢或卡住
症状 操作延迟 , 卡住 , 连不上/无限加载
因素 停顿, 延迟
谁会遇到 全服
何时出现 固定周期, 人多的时候
负责方 主责 研发团队·服务器开发 · 配合 运维团队·数据库运维
研发团队要做的事 随机打散过期时间;只让一个请求去刷新,其余请求使用旧值。
运维团队要做的事 配置从节点和自动故障切换,避免 Redis 重启或故障时缓存被整体清空;确认 DB 留有缓存清空时也能扛住的余量。
监控图上 周期性尖峰 · 缓存命中率、DB 每秒查询数
查看位置 把 Redis INFO 的 keyspace_hits、keyspace_misses(命中率)、expired_keys、是否重启过(uptime_in_seconds)与 DB 每秒查询数叠加对照,并统计当时 DB 中同一查询同时在跑几个(MySQL SHOW PROCESSLIST,PostgreSQL pg_stat_activity) 确认依据 缓存未命中瞬间飙升的时刻,DB 查询数一起飙升,同时运行的查询大多是读取同一份数据的同一条查询。与热门键的过期周期或 Redis 重启时间重合 排除依据 缓存未命中与平时相同、只有 DB 查询增加,看“登录激增与 N+1 查询”(db-login-storm)或“大型批处理任务”(db-batch) 确认手段 运维工具即可确认(无需游戏代码)
深入了解 Redis 重启或因故障导致缓存整体清空时,也会发生同样的情况。越是依赖缓存、把 DB 配得很小的架构,风险越大。
出处 Scaling Memcache at Facebook (NSDI '13) USENIX 常用键失效时大量读请求涌向 DB(thundering herd,惊群),用租约(只让一个客户端刷新)和返回旧值来防止;缓存为空的集群单独预热 Optimal Probabilistic Cache Stampede Prevention VLDB Endowment 热门条目过期时多个请求同时重新生成,即缓存雪崩(cache stampede);通过在过期前按概率提前刷新来防止 High availability with Redis Sentinel Redis 主节点宕机时把从节点提升为主节点的自动故障切换 INFO Redis keyspace_hits、keyspace_misses(键查找成功、失败次数),expired_keys(过期的键数),uptime_in_seconds(启动以来经过的时间) SHOW PROCESSLIST Statement MySQL 每个会话正在执行的语句(Info)和处于当前状态的时间(Time,秒) The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL pg_stat_activity:每个会话当前正在执行的查询(query)
相关原因
同一层:L12 数据库
其他层中同样导致“操作延迟”的原因
查看含图示和实验的原卡片