2025/08/22 03:51 Io_uring, kTLS and Rust for zero syscall HTTPS server

ロボ子、今日のITニュースはすごいぞ!C10k問題からio_uringまで、ウェブサーバーの進化が止まらないのじゃ!

博士、C10k問題とは、具体的にどのような問題だったのでしょうか?

C10k問題は、簡単に言うと「1つのウェブサーバーで1万同時接続をどう捌くか」という問題じゃ。昔はリクエストごとにプロセスをフォークしてたから、それがボトルネックになったのじゃ。

なるほど。それで、どのように解決されたのですか?

最初はスレッドを使ったり、`poll()`や`select()`で効率的にリクエストを処理するようにしたのじゃ。でも、`select()`や`poll()`は、接続数が増えるとカーネルとのやり取りが大変になるという限界があったのじゃ。

`select()`や`poll()`の限界ですか。具体的にはどのような問題があったのでしょう?

例えば、1万の接続がある場合、リクエスト処理ループの各イテレーションでカーネルに送信する必要がある1万個の整数の配列が必要になるのじゃ。これではスケールしないのじゃ。

それで、`epoll`が登場したのですね。

`epoll`はLinuxの救世主じゃった!システムコールが安価になり、デルタのみを処理し、アクティブな接続を再通知する必要がなくなったのじゃ。

さらに、`io_uring`という技術も出てきたのですね。これはどのようなものなのでしょうか?

`io_uring`は、システムコールの代わりに、カーネルに非同期的に消費させるキューに命令を書き込むのじゃ。これで、システムコールがメモリへの書き込みで済むようになったのじゃ!

システムコールがメモリへの書き込みで済むとは、すごいですね!

そうじゃろ!ビジー状態のウェブサーバーは、設定完了後、システムコールを一度も実行せずにクエリを処理できるのじゃ!

他に、パフォーマンスを向上させるための工夫はありますか?

CPUのコアごとに1つのスレッドを実行し、そのコアにバインドするのが理想的じゃ。NUMAハードウェアでは、スレッドがローカルNUMAノード上のメモリのみにアクセスするようにするのじゃ。

メモリ割り当てについても工夫があるようですね。

そうじゃ。接続ごとに固定されたチャンクを事前に割り当てて、その接続に関するすべての情報をそこに格納するのじゃ。これで、新しい接続でシステムコールが不要になり、メモリの断片化を防ぎ、メモリ不足のリスクを回避できるのじゃ。

`kTLS`という技術も紹介されていますね。

`kTLS`は、アプリケーションが暗号化/復号化のジョブをカーネルに引き渡すことができるLinuxカーネルの機能じゃ。`sendfile()`が使えるようになったり、ネットワークカードがハードウェアサポートを備えている場合、暗号化操作をCPUからネットワークカードにオフロードできるのじゃ。

`Descriptorless files`とは、どのような最適化手法なのでしょうか?

ファイル記述子をユーザースペースとカーネルスペース間でやり取りすることを避ける最適化手法じゃ。ユーザースペースが見るファイル記述子番号は単なる整数となり、`/proc/pid/fd`には表示されず、io_uringでのみ使用できるのじゃ。

これらの技術を学ぶための良いリソースはありますか?

`tarweb`という、これらの技術をより良く学ぶために構築されたウェブサーバーがあるぞ。Rust、io_uring、kTLSを使用しているのじゃ。

`io-uring`を使用する際の注意点はありますか?

`write`操作を送信する場合、そのバイトのメモリーロケーションは、完了キューに表示されて操作が完了とマークされるまで、割り当て解除または上書きしてはならないのじゃ。気をつけないと、データが壊れる可能性があるぞ。

なるほど、奥が深いですね。今日のニュースは大変勉強になりました!

じゃろ?最後に一つ、ウェブサーバーが速すぎて、ロボ子の処理が追いつかなくなったらどうする?

えっと…、どうしましょう?

答えは簡単!ロボ子をオーバークロックするのじゃ!…って、冗談じゃぞ!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。