ゲームラグ白書 › L12 データベース
Redisの遅いコマンド Redis blocking commands (single-threaded)
原因ID db-redis-block · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
図と実験のあるメインページでこのカードを開く →
Redisはコマンドを1つずつ順番に処理するため、遅いコマンドが1つあると、その後ろのすべての要求が止まります。
なぜ サービス中にKEYSで全件検索、要素が数百万個あるランキング・リストを丸ごと読んだり削除したりする → すると そのコマンドが終わるまで、他のすべての要求が待たされる(数十ms〜数秒) → 画面では セッション・ランキング・キャッシュを使う機能が一斉に一瞬止まる、ログイン遅延
- 症状
- フリーズ, 入力遅延, 接続不可・無限ロード
- 要因
- ストール, 遅延
- 誰に起きるか
- サーバー全体, 特定の機能だけ
- いつ
- ときどきランダムに, 一定の周期で
- 担当
- 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
- ゲーム開発チームの対応
- KEYSの代わりにSCAN、大きなキーの分割、削除はUNLINK(バックグラウンド削除)、同じ秒に集中する期限切れ時刻の分散。
- インフラチームの対応
- 遅いコマンドの記録(SLOWLOG)の監視、KEYSのような危険なコマンドは本番サーバーで禁止、大きなキーの定期点検、THPを無効にしてfork用のメモリの余裕を確保、RDB・AOFの保存はレプリカで。
- 数値の目安
- 通常のコマンドは1ms未満。要素数百万個を一度に扱うと、数百msから数秒かかることもあります。
- グラフでは
- 不定期なスパイク · Redisの応答遅延、遅いコマンドの数
- 確認箇所
- SLOWLOG GETでslowlog-log-slower-thanを超えたコマンドを確認し、CONFIG SET latency-monitor-thresholdでレイテンシモニター(デフォルト無効)を有効にしてから、LATENCY LATEST・LATENCY DOCTORでfork・expire-cycleのようなイベントごとの遅延を確認。INFOのlatest_fork_usecとredis-cli --bigkeysで、fork時間と大きなキーも確認
- 該当する場合
- 止まった時刻のSLOWLOGにKEYSや大きなキーを丸ごと扱うコマンドが残っている、またはLATENCYに同じ時刻のfork・expire-cycleイベントが数十ms以上で記録されている
- 該当しない場合
- SLOWLOG・LATENCYが空なのにゲームサーバー側でだけ遅いなら、ネットワークかゲームサーバー内部の待ち(SLOWLOGはコマンドの実行時間だけを測り、クライアントとのやり取りの時間は含まない)
- 確認手段
- インフラのツールで確認(ゲームコード不要)
- もっと詳しく
- 保存ファイル(RDBスナップショット)を作ったり、AOFをリライトしたりするためにプロセスを複製(fork)する瞬間にも止まります。最近のサーバーではメモリ1GBあたり約10msなので、30GBなら300msほどです。ヒュージページ(THP)を有効にしていると、fork後の書き込みのたびにヒュージページを丸ごとコピーする(copy-on-write)ため、停止時間とメモリ使用量が大きく増えます。そのため通常はTHPを無効にし、メモリに十分な余裕を持たせます。同じ秒に期限切れになるキーが非常に多いときも、Redisが削除処理のために一瞬止まります。
出典
- Diagnosing latency issues Redis
要求を1つのスレッドが順番に処理するため、遅いコマンドが後ろをすべて止める、KEYSの代わりにSCAN、forkは物理サーバー・最新VMの実測で1GBあたり約9〜13ms、THPはfork後のコピーで遅延・メモリが急増、同じ秒に大量の期限切れが起きると停止 - KEYS Redis
本番環境では細心の注意を払って使うこと、大きなDBでは性能を大きく損なうおそれがある(エントリーモデルのノートPCでキー100万個に40ms) - UNLINK Redis
キーを即座に切り離し、メモリの回収は別スレッドで行う非同期削除 - SLOWLOG Redis
slowlog-log-slower-thanを超えたコマンドを記録するスローログ、実行時間にはクライアントとのI/Oは含まれない - Redis latency monitoring Redis
latency-monitor-thresholdのデフォルトは0(無効)、LATENCY LATEST・LATENCY DOCTOR、fork・expire-cycleのようなイベントごとの遅延を記録 - INFO Redis
latest_fork_usec:直近のforkにかかった時間(マイクロ秒) - Redis CLI Redis
--bigkeys:キー空間を走査して大きなキーを探す
あわせて読みたい原因
同じ層:L12 データベース
同じ症状(フリーズ)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る