# 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]] — 原典記事