한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

游戏卡顿白皮书 › 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 配得很小的架构,风险越大。

出处

  1. Scaling Memcache at Facebook (NSDI '13) USENIX
    常用键失效时大量读请求涌向 DB(thundering herd,惊群),用租约(只让一个客户端刷新)和返回旧值来防止;缓存为空的集群单独预热
  2. Optimal Probabilistic Cache Stampede Prevention VLDB Endowment
    热门条目过期时多个请求同时重新生成,即缓存雪崩(cache stampede);通过在过期前按概率提前刷新来防止
  3. High availability with Redis Sentinel Redis
    主节点宕机时把从节点提升为主节点的自动故障切换
  4. INFO Redis
    keyspace_hits、keyspace_misses(键查找成功、失败次数),expired_keys(过期的键数),uptime_in_seconds(启动以来经过的时间)
  5. SHOW PROCESSLIST Statement MySQL
    每个会话正在执行的语句(Info)和处于当前状态的时间(Time,秒)
  6. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_activity:每个会话当前正在执行的查询(query)

相关原因

同一层:L12 数据库

其他层中同样导致“操作延迟”的原因

查看含图示和实验的原卡片