クライアント1万台問題

クライアント1万台問題
selectの壁とepollのメリットについて学習すべし。
※調査結果
まず、最近の流れとして、多クライアントに対していちいちスレッドを生成するというのはナンセンス。
スレッド生成処理が重いし、リソースも食うから。
よって、1プロセスで多くのクライアントを捌くという流れになっている。
そのための手法として、
・ノンブロッキングI/Oと状態変化通知機構を利用する
・非同期I/Oを使う
を使うのが良いとされている。非同期I/Oはまだメジャーじゃないっぽいので今回は割愛。
状態変化通知機構

状態変化通知(readiness change notification)とは、データが到着して入力が可能になった場合、または先の出力が完了してバッファが空き、次の出力が可能になった場合の変化をユーザプロセスに通知する方式。*BSDのkqueue、Linuxのepoll等がこれに当たる。
従来からUNIXで使われてきたselectやpollは、プログラムが調査するたびにそのとき読み込み可能・出力可能なファイル記述子を報告するもの。selectやpollの大きな問題として、selectには調査するファイル記述子の数がFD_SETSIZEに制約されることが挙げられる。pollにはそのような制約はないものの、C10K環境では毎回長大なファイル記述子のリストを全てスキャンすることになり、多くの場合ほとんどのファイル記述子は準備状態にないだろうことから非常に無駄が多い。
Solarisの/dev/pollはpollを代替するもので、監視するファイル記述子のリストを一回だけ登録し、毎回渡す必要をなくしてパフォーマンスを改善したもの。

要約すると、selectは1024以上のクライアントに対応できないしスキャンも遅い、pollはファイルディスクリプタの制約はないけどスキャンに時間がかかって無駄が多いから、入力がきたら通知してくれるepollとかを使えっていうこと。
ノンブロッキングI/O

ノンブロッキングI/Oは文字通りブロックしない入出力方法。通常の入出力では指定したデータの出力が完了するまで、または指定したバイト数のデータを読み込むまでシステムコールから復帰せず、その間プロセスの実行は停止する。ノンブロッキングI/Oはそのとき到着していたデータだけを読み込み、またはそのときカーネルのバッファに書き込める分量だけを出力して即座に復帰する。1バイトも処理できない場合にはブロックしないでエラー(EWOULDBLOCK)を返す。
この場合にボトルネックはどこからくるかというと、ディスクアクセスで発生する(ディスクアクセスに対してノンブロッキングモードの指定は無効)。mmapされたファイルへのアクセスでも、sendfileでも同様。とにかく読み込むデータがメモリに載っていなかったが最後、ブロックは生じてしまう、すなわち無数のクライアントの処理が停止する。解決策は非同期I/Oを用いるかワーカースレッドに処理を任せてさっさと次のクライアントの処理に回ること。なおFreeBSDにはsendfileにブロックを避けるオプションがある。

要約するとノンブロッキング使えってことでしょうか。
元ネタ:The C10K problem
元ネタの日本語訳:C10K問題

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です