ゲームラグ白書 › L7 サーバーOS(カーネル)
ファイルディスクリプタの上限 File descriptor limit (ulimit)
原因ID so-fd · 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
図と実験のあるメインページでこのカードを開く →
接続ごとにファイルディスクリプタ(fd。OSが開いているファイルやソケットに付ける番号)が必要ですが、1つのプロセスが開けるfdの数には上限があります。
なぜ 同時接続数がプロセスのファイルディスクリプタ上限に到達 → すると サーバーが新しい接続を受け付けられない(Too many open files)。ログファイルやDB接続を開く処理も同時に失敗 → 画面では ちょうど一定の人数から先は誰も入れない接続不可・無限ロード
- 症状
- 接続不可・無限ロード
- 要因
- パケットロス
- 誰に起きるか
- サーバー全体
- いつ
- 接続直後・メンテ明け, 人が集中したとき
- 担当
- 主担当 インフラチーム・サーバーインフラ · 副担当 ゲーム開発チーム・サーバー開発
- ゲーム開発チームの対応
- 接続を終えるときにソケットを確実に閉じる(fdリークの防止)、acceptがEMFILE(fd不足)で失敗したら接続の受け付けをしばらく止めるか、あらかじめ確保しておいた予備のfdで受け付けてすぐ閉じる(同じ接続通知だけを繰り返し処理してCPUを浪費しないように)。
- インフラチームの対応
- ulimit・サービス設定(systemdのLimitNOFILE)の確認、上限に近づいたときのアラート。
- 数値の目安
- Linuxでは、サービスの設定を個別に変えない限り上限が1,024のままの場合がまだ多くあります。ゲームサーバーでは通常、数万〜数十万に引き上げます。Windowsにはこのような低いデフォルトの上限はありません。
- グラフでは
- 上限で頭打ち · プロセスが開いているfd数、同時接続数
- 確認箇所
- pidstat -vでゲームサーバープロセスのfd-nr(開いているファイルディスクリプタ数)を、/proc/PID/limitsで開けるファイル数の上限を確認し、サーバーログからacceptの失敗(EMFILE、Too many open files)を探す
- 該当する場合
- fd数が上限値で頭打ちになり、その時刻からacceptがEMFILEで失敗している
- 該当しない場合
- fd数が上限に遠く及ばなければこの原因ではない。接続要求がカーネルで破棄されていれば「接続待ちキュー(backlog)のあふれ」、接続追跡の問題なら「サーバーのconntrackテーブル飽和」
- 確認手段
- インフラのツールで確認(ゲームコード不要)
- もっと詳しく
- 受け付けられなかった接続はカーネルの接続待ちキュー(backlog)にそのまま残るため、サーバーのコードによっては「新しい接続あり」の通知を受け続けてCPUを浪費することもあります。
出典
- systemd-system.conf(5) — Linux manual page systemd
サービスのDefaultLimitNOFILEのデフォルト値は1024:524288(ソフトリミット1,024) - accept(2) — Linux manual page Linux man-pages
プロセスのfd上限に達するとacceptがEMFILEで失敗 - Maximum Number of Sockets Supported Microsoft
WindowsのWinsockはソケット数を利用可能なメモリ量でのみ制限 - pidstat(1) — Linux manual page sysstat
-vのfd-nr:プロセスが開いているファイルディスクリプタ数 - proc_pid_limits(5) — Linux manual page Linux man-pages
/proc/PID/limitsに、プロセスごとのリソース上限のソフト・ハードの値
あわせて読みたい原因
同じ層:L7 サーバーOS(カーネル)
同じ症状(接続不可・無限ロード)を起こすほかの層の原因
図と実験のあるメインページでこのカードを見る