GNU/Linux >> Linux の 問題 >  >> Linux

Linux には本当に非同期ブロック I/O がないのでしょうか?

(2020) 5.1 以上の Linux カーネルを使用している場合は、io_uring を使用できます ファイルのような I/O 用のインターフェイスを提供し、優れた非同期操作を取得します。

既存の libaio との比較 /KAIO インターフェイス、io_uring 次の利点があります:

  • (直接 I/O を実行するときだけでなく) バッファ I/O を実行するときに非同期動作を保持します
  • 使いやすい (特に liburing を使用する場合) ヘルパー ライブラリ)
  • オプションでポーリング方式で動作できます (ただし、このモードを有効にするには、より高い権限が必要です)
  • I/O ごとの簿記スペースのオーバーヘッドが少ない
  • ユーザー空間/カーネル syscall モードの切り替えが少ないため、CPU オーバーヘッドが削減されます (スペクター/メルトダウンの軽減策の影響により、最近では大きな問題になっています)
  • ファイル記述子とバッファを事前登録して、マッピング/アンマッピング時間を節約できます
  • より高速 (より高い総スループットを達成でき、I/O のレイテンシーがより低くなります)
  • 「リンク モード」は、I/O 間の依存関係を表現できます (>=5.3 カーネル)
  • ソケットベースの I/O (recvmsg()) で動作可能 /sendmsg()>=5.3 からサポートされています。io_uring.c の git history でサポートという言葉に言及しているメッセージを参照してください)
  • キューに入れられた I/O のキャンセル試行をサポート (>=5.5)
  • その I/O を常に要求できます インライン送信パスがブロックをトリガーしたときに、I/O を非同期コンテキストにパントするだけにフォールバックするデフォルトではなく、非同期コンテキストから実行する (>=5.6 カーネル)
  • read 以降の非同期操作の実行に対するサポートの拡大 /write (例:fsync (>=5.1)、fallocate (>=5.6)、splice (>=5.7) 以上)
  • 発展の勢い
  • 星が完全に揃わないたびにブロックされることはありません

glibc の POSIX AIO と比較すると、io_uring 次の利点があります:

  • かなり より高速で効率的 (上記のオーバーヘッド削減の利点は、ここでもさらに適用されます)
  • インターフェイスはカーネルでサポートされており、ユーザー空間のスレッド プールを使用しません
  • バッファリングされた I/O を実行するときに作成されるデータのコピーが少なくなります
  • 合図と格闘しない
  • Glibc の POSIX AIO は、io_uring に対して、1 つのファイル記述子で複数の I/O を飛行中に持つことはできません。 間違いなくできます!

Efficient IO with io_uring ドキュメントは、io_uring に関してさらに詳しく説明しています。 のメリットと使い方。 What's new with io_uring ドキュメントでは、io_uring に追加された新機能について説明しています io_uringLWN の急速な成長の記事では、5.1 から 5.5 のカーネルのそれぞれでどの機能が利用可能であったかを説明し、5.6 でどうなるかを概観しています (LWN の io_uring 記事のリストも参照してください)。 io_uring による Faster IO through io_uring Kernel Recipes ビデオ プレゼンテーション (スライド) は 2019 年後半から、What's new with io_uring Kernel Recipes ビデオ プレゼンテーション (スライド) は 2022 年半ばからです。 著者のイェンス・アクスボー。最後に、io_uring チュートリアルの主が io_uring を紹介します

io_uring コミュニティには io_uring メーリング リストからアクセスでき、io_uring メーリング リストのアーカイブは 2021 年初頭の毎日のトラフィックを示しています。

Re "recv() の意味で部分 I/O をサポート vs read() ":io_uring を自動的に再試行するパッチが 5.3 カーネルに入りました 短い読み取りと、REQ_F_NOWAIT を設定していないリクエストで「通常の」ファイルを操作するときに、短い読み取りのみを自動的に処理するように動作を調整する 5.4 カーネルにさらにコミットが入りました。 フラグ (REQ_F_NOWAIT をリクエストできるようです) IOCB_NOWAIT経由 または O_NONBLOCK でファイルを開く )。したがって、recv() を取得できます style- io_uring からの「短い」I/O 動作

io_uring を使用したソフトウェア/プロジェクト

インターフェイスは新しいものですが (最初の化身は 2019 年 5 月に登場しました)、一部のオープンソース ソフトウェアは io_uring を使用しています。 "野生":

  • fio (これも Jens Axboe によって作成されています) には io_uring ioengine バックエンドがあります (実際には、2019 年 2 月の fio-3.13 で導入されました!)。 2 人の Intel エンジニアによる「新しい Linux カーネル I/O インターフェイス SNIA を使用したスト​​レージ パフォーマンスの向上に関するプレゼンテーション」(スライド) では、1 つのワークロードで IOPS を 2 倍にし、キューの深さ 1 で平均レイテンシを半分以下にすることができたと述べています。 io_uring を比較するときの別のワークロード ioengine を libaio に Optane デバイス上の ioengine。
  • SPDK プロジェクトは、v19.04 リリースで、ブロック デバイス アクセスに io_uring (!) を使用するためのサポートを追加しました (ただし、これは、ベンチマーク以外で通常 SPDK を使用するバックエンドではありません)。最近では、v20.04 でソケットを使用するためのサポートも追加されたようです...
  • Ceph は、15.1.0 リリースの一部である io_uring バックエンドを 2019 年 12 月にコミットしました。コミットの作成者は、一部の io_uring バックエンドが libaio バックエンドと比べて (IOPS、帯域幅、レイテンシーに関して) ワークロードに応じて勝敗があることを示す github コメントを投稿しました。
  • RocksDB が io_uring をコミットしました 2019 年 12 月の MultiRead のバックエンドであり、6.7.3 リリースの一部でした。 Jens は io_uring を述べています 待ち時間を劇的に短縮するのに役立ちました。
  • libev は最初の io_uring で 4.31 をリリースしました 2019 年 12 月のバックエンド。著者の元のポイントのいくつかは新しいカーネルで対処されましたが、執筆時点 (2021 年半ば) で、libev の著者は io_uring についていくつかの選択の言葉を持っています。 の成熟度を見極め、さらなる改善を実施する前に様子見のアプローチを取っています。
  • QEMU は 2020 年 1 月に io_uring バックエンドをコミットし、QEMU 5.0 リリースの一部でした。 「QEMU の io_uring:Linux の高性能ディスク IO」PDF プレゼンテーションで、Julia Suvorova が io_uring を示しています。 threads を上回るバックエンド と aio ランダムな 16K ブロックの 1 つのワークロードのバックエンド。
  • Samba は io_uring をマージしました 2020 年 2 月の VFS バックエンドで、Samba 4.12 リリースの一部でした。 「Linux io_uring VFS バックエンド」。 Samba メーリング リスト スレッド、Stefan Metzmacher (コミット作成者) は io_uring と述べています モジュールは、合成テストで (特定されていないバックエンドと比較して) 約 19% 多いスループットをプッシュすることができました。変更の背後にある動機の一部については、Stefan による「Async VFS Future」PDF プレゼンテーションを読むこともできます。
  • Facebook の実験的な C++ libunifex はそれを使用します (ただし、5.6+ カーネルも必要です)
  • Rust の人々は io_uring を作るためのラッパーを書いています。 純粋な錆にアクセスしやすくなります。 rio は少し話題になったライブラリの 1 つであり、著者は、スレッドにラップされた同期呼び出しを使用する場合と比較して、より高いスループットを達成したと述べています。著者は FOSDEM 2020 で彼のデータベースとライブラリについてプレゼンテーションを行い、io_uring の美徳を称賛するセクションが含まれていました。 .
  • Rust ライブラリ Glommio は io_uring のみを使用します .著者 (Glauber Costa) は、Modern storage is pretty fast というドキュメントを公開しました。 Glommio を慎重に調整することで、通常の 2.5 倍以上のパフォーマンスを得ることができることを示しているのは、悪い API です (non-io_uring) ) Optane デバイスでシーケンシャル I/O を実行するときのシステムコール。
  • Gluster は 2020 年 10 月に io_uring posix xlator をマージし、Gluster 9.0 リリースの一部でした。コミットの作成者は、パフォーマンスが「通常の pwrite/pread syscall よりも悪くない」と述べています。

io_uring を使用して調査するソフトウェア

  • PostgreSQL 開発者の Andres Freund は、io_uring の原動力の 1 人です。 改善 (例:ファイルシステムの inode 競合を減らすための回避策)。 「Asynchronous IO for PostgreSQL」というプレゼンテーションがあります (ビデオは 5 分のマークまで壊れていることに注意してください) (PDF) は、PostgreSQL の変更の必要性を動機付け、いくつかの実験結果を示しています。彼はオプションの io_uring を手に入れたいという希望を表明しました PostgreSQL 14 へのサポートを開始し、カーネル レベルに至るまで、何が機能し、何が機能しないかを鋭く認識しているようです。 2020 年 12 月、Andres は彼の PostgreSQL io_uring についてさらに議論します。 「Blocking I/O, async I/O and io_uring」pgsql-hackers メーリング リスト スレッドで作業し、進行中の作業については https://github.com/anarazel/postgres/tree/aio で確認できると述べています。 /li>
  • Netty プロジェクトには、io_uring で動作するインキュベーター リポジトリがあります。 5.9 カーネルを必要とするサポート
  • libuv には、io_uring を追加するプル リクエストがあります。 サポートされていますが、プロジェクトへの進行が遅い
  • SwiftNIO が io_uring を追加しました 2020 年 4 月のイベンティング (syscall ではない) のサポートと Linux:完全な io_uring I/O の問題は、それをさらに統合する計画の概要を示しています
  • Tokio Rust プロジェクトは概念実証 tokio-uring を開発しました

io_uring の Linux ディストリビューションのサポート

  • (2020 年後半) Ubuntu 18.04 の最新の HWE 有効化カーネルは 5.4 なので io_uring syscall を使用できます。このディストリビューションは liburing をあらかじめパッケージ化していません ヘルパー ライブラリですが、自分で構築することもできます
  • Ubuntu 20.04 の初期カーネルは 5.4 なので io_uring syscall を使用できます。上記のように、ディストリビューションは liburing を事前にパッケージ化していません .
  • Fedora 32 の初期カーネルは 5.6 および パッケージ化された liburing があります だから io_uring 使用可能です。
  • SLES 15 SP2 には 5.3 カーネルがあるため、io_uring syscall を使用できます。このディストリビューションは liburing をあらかじめパッケージ化していません ヘルパー ライブラリですが、自分で構築することもできます
  • (2021 年半ば) RHEL 8 のデフォルト カーネルはしない io_uring をサポート (この回答の以前のバージョンでは、誤ってそうだと言っていました)。 「進行中」の Add io_uring サポート Red Hat ナレッジベース記事 (コンテンツはサブスクライバー ペイウォールの背後にあります) があります。
  • (2022 年半ば) RHEL 9 のデフォルト カーネルはしない io_uring をサポート .カーネルは十分に新しい (5.14) ですが、io_uring をサポートしています は明示的に無効になっています。

できれば io_uring Linux の非同期ファイルのような I/O ストーリーの先駆けとなるでしょう。

(この回答に信憑性の薄いベニアを追加するために、過去のある時点で、Jens Axboe (Linux カーネル ブロック レイヤーのメンテナーおよび io_uring の発明者) ) この回答は賛成する価値があると思いました :-)


Peter Teoh によって間接的に指摘された本当の答えは、io_setup() と io_submit() に基づいています。効率的な実装です。本当の答えは次のとおりです。

io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)

2012 年 8 月付けのマニュアル ページによると、この実装は glibc ユーザー空間エミュレーションを置き換えることができる点まではまだ成熟していません。

http://man7.org/linux/man-pages/man7/aio.7.html

<ブロック引用>

この実装は、カーネル システム コールを使用して POSIXAIO 実装を完全に再実装できるほど成熟していません。

そのため、私が見つけた最新のカーネル ドキュメントによると、Linux にはまだ成熟したカーネル ベースの非同期 I/O モデルがありません。そして、文書化されたモデルが実際に成熟していると仮定すると、recv() と read() の意味での部分的な I/O はまだサポートされていません。


Linux
  1. Linuxで「中断できない」プロセスを停止するには?

  2. Linux と I/O 完了ポート?

  3. Linux に STDCALL はありますか?

  1. node.js の内部非同期 I/O メカニズムに関する混乱

  2. Linux での I/O エラー:root としてディレクトリを削除できません

  3. Linux:I/O の top に似たものはありますか?

  1. Linux I/O レイテンシーのデバッグ

  2. Linux で LD_PRELOAD と LD_LIBRARY_PATH をブロックする方法はありますか?

  3. Linux での CPU I/O 待機の評価