# C10K問題 ## 定義 **C10K問題**とは、1台のサーバで**同時に 10,000 クライアント**を処理するための I/O アーキテクチャ上の課題である。[[Dan Kegel]] が 1999 年に命名・整理した([[C10K-Problem]])。 「C」は Clients、「10K」は 10,000 を意味する。1999年当時、ハードウェア(1GHz CPU・2GB RAM・1Gbps NIC)のコストは $1200 程度に下がっており、問題はハードウェアではなく OS とアプリケーションの I/O 戦略にあると指摘された。 ## 問題の本質 従来の **1プロセス/スレッド per クライアント**モデルは、数百クライアントでは問題ないが、数千になるとコンテキストスイッチとメモリ消費が爆発する。 - デフォルト 2MB スタック × 10,000 スレッド = 20GB → 32ビット環境では不可能 - select() は FD_SETSIZE(通常 1024)の上限を持つ - poll() は O(n) スキャンで大量アイドル記述子に弱い ## I/O 戦略の5分類 [[Dan Kegel]] が整理した5戦略: ### 1. 非ブロッキング I/O + レベルトリガ通知 記述子が ready な限り繰り返し通知する。`select()` / `poll()` / `/dev/poll`(Solaris) / [[kqueue]](BSD)。 **ディスク I/O の落とし穴**: ページがメモリにない場合 `sendfile()` もブロック。`mincore()` で事前検知 → ワーカーへ委譲(Flash Web Server の手法)。 ### 2. 非ブロッキング I/O + エッジトリガ通知(現代の主流) not-ready → ready への**遷移**時のみ通知。[[epoll]](Linux 2.6)・[[kqueue]](BSD)がこれを支援。見落とし厳禁だが、接続数に対してスケールする。 ### 3. 非同期 I/O + 完了通知 POSIX `aio_*` / Linux AIO / Windows IOCP。I/O 完了時にシグナルまたはキューで通知。 ### 4. スレッド1本 per クライアント ブロッキング read/write で簡単に書ける。NPTL(Linux)の登場で 1:1 モデルが実用的になったが、大量スレッドは依然メモリを圧迫する。 ### 5. カーネル内サーバ TUX(Ingo Molnar)・khttpd など。最高速だが汎用性が低く、コミュニティは「カーネル機能強化でユーザー空間から恩恵を得る」方向を選択。 ## レベルトリガ vs エッジトリガ | 項目 | レベルトリガ | エッジトリガ | |-----|------------|------------| | 通知タイミング | ready 状態が続く限り | not-ready→ready の遷移時のみ | | 実装例 | select, poll, /dev/poll | [[epoll]] EPOLLET, [[kqueue]] EV_CLEAR | | 見落としリスク | 低(繰り返し通知) | 高(見落とすと永遠にストール) | | スケーラビリティ | 低(記述子スキャン) | 高(差分のみ処理) | ## チューニング要素 - **`sendfile()`** — カーネルがファイルをソケットへ直接転送(コピー削減) - **ゼロコピー** — aligned pointer + ページサイズ以上の転送でコピー回避 - **`TCP_CORK`** — 小さな write をまとめて1フレームで送出 - **ファイルハンドル上限** — `ulimit -n 32768` / `/proc/sys/fs/file-max` - **過負荷制御** — ready I/O 数を平滑化した指標で新規接続を積極拒否 ## 歴史的影響 C10K問題の整理が [[epoll]](Linux 2.5.46、2002)・[[kqueue]](FreeBSD 4.1、2000)の標準化を後押しし、[[nginx]](2004)・libevent・Node.js・Go の `net` ライブラリなど現代の高並行サーバ/フレームワークの設計基盤となった。 > [!key-insight] 現代への接続 > C10K は 1999 年の問題だが、「どのイベント通知機構を使うか」という選択は今も有効。Linux では [[epoll]]、BSD/macOS では [[kqueue]]、Windows では IOCP が正解であり、libuv・Tokio・asyncio などがこれらをラップしている。 ## 関連 - [[epoll]] — Linux の解 - [[kqueue]] — BSD の解 - [[インターネットスケールサービス設計]] — 同時代の運用設計思想 - [[C10K-Problem]] — 原典記事