ゲームラグ白書 › L12 データベース
キャッシュスタンピード Cache stampede / thundering herd
原因ID db-cache-stampede · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
図と実験のあるメインページでこのカードを開く →
人気データのキャッシュが同時に期限切れになると、数千件の要求が一斉にDBへ殺到します。
なぜ Redisなどに保存した人気データが同時に期限切れ → すると 同じデータを作り直そうとする要求が一斉にDBへ殺到 → 画面では DBの過負荷で複数の機能が次々に遅くなったり止まったりする
- 症状
- 入力遅延, フリーズ, 接続不可・無限ロード
- 要因
- ストール, 遅延
- 誰に起きるか
- サーバー全体
- いつ
- 一定の周期で, 人が集中したとき
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
- ゲーム開発チームの対応
- 期限切れの時刻をランダムに分散、1つの要求だけが更新し残りは古い値を使う。
- インフラチームの対応
- 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のクエリだけが増えるなら、ログイン殺到(db-login-storm)かバッチ(db-batch)
- 確認手段
- インフラのツールで確認(ゲームコード不要)
- もっと詳しく
- Redisが再起動したり、障害でキャッシュが丸ごと空になったりしても、同じことが起きます。キャッシュを当てにしてDBを小さく見積もった構成ほど危険です。
出典
- Scaling Memcache at Facebook (NSDI '13) USENIX
よく使うキーが無効化されると大量の読み取りがDBに殺到するthundering herd、リース(1つのクライアントだけが更新)・古い値の返却で防ぐ、キャッシュが空のクラスターは別途ウォームアップ - Optimal Probabilistic Cache Stampede Prevention VLDB Endowment
人気の項目が期限切れになると複数の要求が同時に再生成するキャッシュスタンピード、期限切れの前に確率的に先回りして更新して防ぐ - 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 データベース
同じ症状(入力遅延)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る