システムへの各呼び出しには、ユーザーモードからカーネルモードへの切り替え、状態の保存、パラメータのチェックといった処理が伴います。1秒間に数十万回の操作を処理するサーバーでは、こうしたコストが積み重なってかなりの割合を占めることになります。
2つの共有ガスケット
io_uringは、プログラムとカーネルの両方がアクセスできるメモリ領域内に、2つの循環キューを構築します:
- 送信データ — ここにリクエストを記録するプログラム
- 受信データ — 返された結果を記録する
プログラムは数十の操作をキューに格納し、カーネルに一度だけ通知することができます。プローブスレッドモードでは、システムコールさえ必要とせず、カーネルが新しい要求を自動的に検知します。
これまでの方法と何が違うのか
epoll ファイルの準備が整ったことを知らせるインジケーターですが、その後も自分で呼び出しを行う必要があります read。待機段階では非同期ですが、処理段階では同期です。io_uringは両方が非同期です:読み取りリクエストを送信し、完了時に結果を受け取ります。
それはソケットだけに限定されるわけではありません。通常のファイルの読み書き、ファイルのオープン、名前の変更、さらには相互に依存する一連の操作でさえも、その範疇に含まれます。
代償
攻撃対象領域が広くなる上、過去には一連の脆弱性が発見されたため、一部のプロバイダーはマルチユーザー環境でのio_uringの使用を制限しています。また、プログラミングもより複雑になります。実行中の操作におけるバッファのライフサイクル管理は、エラーが発生しやすい箇所です。
アプリケーションがシステムコール数によってボトルネックになっていない場合、io_uring は複雑さを増すだけで何のメリットもありません。事前に測定を行ってください。
Thảo luận