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

ゲームラグ白書 › 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が削除処理のために一瞬止まります。

出典

  1. Diagnosing latency issues Redis
    要求を1つのスレッドが順番に処理するため、遅いコマンドが後ろをすべて止める、KEYSの代わりにSCAN、forkは物理サーバー・最新VMの実測で1GBあたり約9〜13ms、THPはfork後のコピーで遅延・メモリが急増、同じ秒に大量の期限切れが起きると停止
  2. KEYS Redis
    本番環境では細心の注意を払って使うこと、大きなDBでは性能を大きく損なうおそれがある(エントリーモデルのノートPCでキー100万個に40ms)
  3. UNLINK Redis
    キーを即座に切り離し、メモリの回収は別スレッドで行う非同期削除
  4. SLOWLOG Redis
    slowlog-log-slower-thanを超えたコマンドを記録するスローログ、実行時間にはクライアントとのI/Oは含まれない
  5. Redis latency monitoring Redis
    latency-monitor-thresholdのデフォルトは0(無効)、LATENCY LATEST・LATENCY DOCTOR、fork・expire-cycleのようなイベントごとの遅延を記録
  6. INFO Redis
    latest_fork_usec:直近のforkにかかった時間(マイクロ秒)
  7. Redis CLI Redis
    --bigkeys:キー空間を走査して大きなキーを探す

あわせて読みたい原因

同じ層:L12 データベース

同じ症状(フリーズ)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る