(2020) Wenn Sie einen Linux-Kernel 5.1 oder höher verwenden, können Sie den io_uring
verwenden Schnittstelle für dateiähnliche E/A und erhalten einen hervorragenden asynchronen Betrieb.
Verglichen mit dem bestehenden libaio
/KAIO-Schnittstelle, io_uring
hat folgende Vorteile:
- Behält asynchrones Verhalten bei gepufferter E/A bei (und nicht nur bei direkter E/A)
- Einfacher zu verwenden (insbesondere bei Verwendung des
liburing
Hilfsbibliothek) - Kann optional auf abgefragte Weise arbeiten (aber Sie benötigen höhere Berechtigungen, um diesen Modus zu aktivieren)
- Weniger Buchhaltungsaufwand pro I/O
- Geringerer CPU-Overhead durch weniger Userspace/Kernel-Syscall-Modus-Wechsel (heutzutage eine große Sache aufgrund der Auswirkungen von Spectre/Meltdown-Mitigationen)
- Dateideskriptoren und Puffer können vorab registriert werden, um Mapping-/Unmapping-Zeit zu sparen
- Schneller (kann einen höheren Gesamtdurchsatz erreichen, I/Os haben eine geringere Latenz)
- "Linked Mode" kann Abhängigkeiten zwischen I/Os ausdrücken (>=5.3 Kernel)
- Kann mit Socket-basierter E/A arbeiten (
recvmsg()
/sendmsg()
werden ab>=5.3 unterstützt, siehe Meldungen, die das Wort support in der Git-Historie von io_uring.c erwähnen) - Unterstützt den versuchten Abbruch von E/A in der Warteschlange (>=5.5)
- Kann diese E/A immer anfordern aus einem asynchronen Kontext ausgeführt werden, anstatt standardmäßig nur dann auf die Ein-/Ausgabe in einen asynchronen Kontext zurückzugreifen, wenn der Inline-Übermittlungspfad eine Blockierung auslöst (>=5.6-Kernel)
- Zunehmende Unterstützung für die Durchführung asynchroner Operationen über
read
hinaus /write
(zBfsync
(>=5.1),fallocate
(>=5.6),splice
(>=5.7) und mehr) - Höhere Entwicklungsdynamik
- Wird nicht jedes Mal blockieren, wenn die Sterne nicht perfekt ausgerichtet sind
Verglichen mit POSIX AIO von glibc, io_uring
hat folgende Vorteile:
- Viel schneller und effizienter (die geringeren Overhead-Vorteile von oben gelten hier noch mehr)
- Die Schnittstelle ist Kernel-unterstützt und verwendet KEINEN Userspace-Thread-Pool
- Bei gepufferter E/A werden weniger Kopien der Daten erstellt
- Kein Ringen mit Signalen
- Glibcs POSIX AIO kann nicht mehr als eine I/O in Flight auf einem einzigen Dateideskriptor haben, wohingegen
io_uring
ganz sicher!
Das Dokument Efficient IO with io_uring geht weit detaillierter auf io_uring
ein Vorteile und Verwendung. Das Dokument What's new with io_uring beschreibt neue Funktionen, die zu io_uring
hinzugefügt wurden zwischen den Kerneln 5.2 - 5.5, während der LWN-Artikel Das schnelle Wachstum von io_uring beschreibt, welche Funktionen in jedem der Kernel 5.1 - 5.5 verfügbar waren, mit einem Ausblick auf das, was in 5.6 enthalten sein würde (siehe auch LWNs Liste der io_uring-Artikel). Es gibt auch eine Videopräsentation (Folien) von Faster IO through io_uring Kernel Recipes von Ende 2019 und eine Videopräsentation (Folien) von What’s new with io_uring Kernel Recipes von Mitte 2022 von io_uring
Autor Jens Axboe. Schließlich gibt das Lord of the io_uring Tutorial eine Einführung in io_uring
Nutzung.
Die io_uring
Die Community kann über die io_uring-Mailingliste erreicht werden und die io_uring-Mailinglistenarchive zeigen den täglichen Datenverkehr Anfang 2021.
Bezüglich "partial I/O im Sinne von recv()
unterstützen gegenüber read()
":Ein Patch wurde in den 5.3-Kernel eingefügt, der automatisch io_uring
wiederholt Short Reads und ein weiterer Commit gingen in den 5.4-Kernel, der das Verhalten so optimiert, dass nur Short Reads automatisch berücksichtigt werden, wenn mit "normalen" Dateien auf Anfragen gearbeitet wird, die den REQ_F_NOWAIT
nicht gesetzt haben Flag (es sieht so aus, als könnten Sie REQ_F_NOWAIT
anfordern über IOCB_NOWAIT
oder durch Öffnen der Datei mit O_NONBLOCK
). So erhalten Sie recv()
style- "kurzes" E/A-Verhalten von io_uring
auch.
Software/Projekte mit io_uring
Obwohl die Schnittstelle noch jung ist (ihre erste Inkarnation erschien im Mai 2019), verwendet einige Open-Source-Software io_uring
"in freier Wildbahn":
- fio (das ebenfalls von Jens Axboe verfasst wurde) hat ein io_uring ioengine-Backend (tatsächlich wurde es bereits in fio-3.13 vom Februar 2019 eingeführt!). Die Präsentation „Improved Storage Performance Using the New Linux Kernel I/O Interface SNIA“ (Folien) von zwei Intel-Ingenieuren gibt an, dass sie bei einer Arbeitslast die doppelte IOPS und weniger als die Hälfte der durchschnittlichen Latenz bei einer Warteschlangentiefe von 1 erreichen konnten eine andere Arbeitsbelastung beim Vergleich von
io_uring
ioengine zumlibaio
ioengine auf einem Optane-Gerät. - Das SPDK-Projekt hat in seiner Version v19.04 Unterstützung für die Verwendung von io_uring (!) für den Zugriff auf Blockgeräte hinzugefügt (aber offensichtlich ist dies nicht das Backend, für das Sie SPDK normalerweise für andere Zwecke als Benchmarking verwenden würden). In jüngerer Zeit scheinen sie auch Unterstützung für die Verwendung mit Sockets in v20.04 hinzugefügt zu haben ...
- Ceph hat im Dezember 2019 ein io_uring-Backend festgeschrieben, das Teil seiner Version 15.1.0 war. Der Commit-Autor hat einen Github-Kommentar gepostet, der zeigt, dass ein io_uring-Backend je nach Arbeitslast einige Gewinne und Verluste gegenüber dem libaio-Backend (in Bezug auf IOPS, Bandbreite und Latenz) aufweist.
- RocksDB hat einen
io_uring
begangen Backend für MultiRead im Dezember 2019 und war Teil der Version 6.7.3. Jens gibtio_uring
an hat dazu beigetragen, die Latenzzeit drastisch zu reduzieren. - libev veröffentlichte 4.31 mit einem anfänglichen
io_uring
Backend im Dezember 2019. Während einige der ursprünglichen Punkte des Autors in neueren Kerneln angesprochen wurden, hat der Autor von libev zum Zeitpunkt des Schreibens (Mitte 2021) einige auserlesene Worte zuio_uring
ausgereift und wartet ab, bevor weitere Verbesserungen implementiert werden. - QEMU hat im Januar 2020 ein io_uring-Backend festgeschrieben und war Teil der Veröffentlichung von QEMU 5.0. In der PDF-Präsentation „io_uring in QEMU:high-performance disk IO for Linux“ zeigt Julia Suvorova den
io_uring
Backend, dasthreads
übertrifft undaio
Backends auf einer Workload von zufälligen 16K-Blöcken. - Samba hat einen
io_uring
zusammengeführt VFS-Backend im Februar 2020 und war Teil der Veröffentlichung von Samba 4.12. Im "Linux io_uring VFS-Backend". Samba-Mailinglisten-Thread, Stefan Metzmacher (der Commit-Autor) sagt denio_uring
-Modul konnte in einem synthetischen Test etwa 19 % mehr Durchsatz (im Vergleich zu einem nicht näher bezeichneten Backend) erreichen. Sie können auch die PDF-Präsentation "Async VFS Future" von Stefan lesen, um einige der Gründe für die Änderungen zu erfahren. - Facebooks experimentelles C++ libunifex verwendet es (aber Sie benötigen auch einen 5.6+ Kernel)
- Die Rust-Leute haben Wrapper geschrieben, um
io_uring
zu machen zugänglicher für reinen Rost. rio ist eine Bibliothek, über die ein wenig gesprochen wird, und der Autor sagt, dass sie im Vergleich zur Verwendung von in Threads eingebetteten Synchronisierungsaufrufen einen höheren Durchsatz erzielt haben. Der Autor hielt auf der FOSDEM 2020 eine Präsentation über seine Datenbank und Bibliothek, die einen Abschnitt enthielt, in dem die Vorzüge vonio_uring
gepriesen wurden . - Die Rostbibliothek Glommio verwendet ausschließlich
io_uring
. Der Autor (Glauber Costa) hat ein Dokument namens Modern storage is much fast veröffentlicht. Es sind die APIs, die schlecht sind und zeigen, dass Glommio bei sorgfältiger Abstimmung mehr als das 2,5-fache der Leistung gegenüber regulären (nicht-io_uring
) erreichen könnte ) Systemaufrufe, wenn sequenzielle E/A auf einem Optane-Gerät ausgeführt werden. - Gluster hat im Oktober 2020 einen io_uring posix xlator zusammengeführt und war Teil der Gluster 9.0-Version. Der Commit-Autor erwähnt, dass die Leistung "nicht schlechter als normale pwrite/pread-Systemaufrufe" war.
Software untersucht mit io_uring
- Der PostgreSQL-Entwickler Andres Freund war eine der treibenden Kräfte hinter
io_uring
Verbesserungen (z. B. die Problemumgehung, um Dateisystem-Inode-Konflikte zu reduzieren). Es gibt eine Präsentation „Asynchronous IO for PostgreSQL“ (beachten Sie, dass das Video bis zur 5-Minuten-Marke unterbrochen ist) (PDF), die die Notwendigkeit von PostgreSQL-Änderungen begründet und einige experimentelle Ergebnisse demonstriert. Er hat die Hoffnung geäußert, seinen optionalenio_uring
zu erhalten Unterstützung in PostgreSQL 14 und scheint genau zu wissen, was funktioniert und was nicht, sogar bis auf die Kernel-Ebene. Im Dezember 2020 diskutiert Andres weiter sein PostgreSQLio_uring
Arbeit im Pgsql-Hackers-Mailinglisten-Thread „Blocking I/O, async I/O and io_uring“ und erwähnt, dass die laufende Arbeit unter https://github.com/anarazel/postgres/tree/aio eingesehen werden kann /li> - Das Netty-Projekt hat ein Inkubator-Repo, das an
io_uring
arbeitet Unterstützung, die einen 5.9-Kernel benötigt - libuv hat eine Pull-Anforderung dagegen, die
io_uring
hinzufügt Unterstützung, aber der Fortschritt in das Projekt war langsam - SwiftNIO hat
io_uring
hinzugefügt Unterstützung für Eventing (aber nicht Systemaufrufe) im April 2020 und die Ausgabe Linux:full io_uring I/O skizziert Pläne zur weiteren Integration - Das Tokio-Rust-Projekt hat einen Proof-of-Concept-Tokio-uring entwickelt
Linux-Distributionsunterstützung für io_uring
- (Ende 2020) Der neueste HWE-Enablement-Kernel von Ubuntu 18.04 ist 5.4, also
io_uring
Systemaufrufe können verwendet werden. Diese Distribution enthält denliburing
nicht vorab Hilfsbibliothek, aber Sie können sie selbst erstellen. - Der anfängliche Kernel von Ubuntu 20.04 ist 5.4, also
io_uring
Systemaufrufe können verwendet werden. Wie oben, enthält die Distributionliburing
nicht vorkonfiguriert . - Der anfängliche Kernel von Fedora 32 ist 5.6 und es hat einen verpackten
liburing
alsoio_uring
nutzbar ist. - SLES 15 SP2 hat einen 5.3-Kernel, also
io_uring
Systemaufrufe können verwendet werden. Diese Distribution enthält denliburing
nicht vorab Hilfsbibliothek, aber Sie können sie selbst erstellen. - (Mitte 2021) Der Standardkernel von RHEL 8 nicht unterstützt
io_uring
(Eine frühere Version dieser Antwort sagte fälschlicherweise, dass dies der Fall sei). Es gibt einen Red Hat Knowledge Base-Artikel zur Unterstützung von io_uring hinzufügen (der Inhalt befindet sich hinter einer Abonnenten-Paywall), der "in Bearbeitung" ist. - (Mitte 2022) Der Standardkernel von RHEL 9 nicht unterstützt
io_uring
. Der Kernel ist neu genug (5.14), aber Unterstützung fürio_uring
ist explizit deaktiviert.
Hoffentlich io_uring
wird eine bessere asynchrone dateiähnliche E/A-Story für Linux einleiten.
(Um dieser Antwort einen Hauch von Glaubwürdigkeit hinzuzufügen, irgendwann in der Vergangenheit hat Jens Axboe (Betreuer der Linux-Kernel-Blockschicht und Erfinder von io_uring
) dachte, dass diese Antwort eine positive Bewertung wert sein könnte :-)
Die eigentliche Antwort, auf die Peter Teoh indirekt hingewiesen hat, basiert auf io_setup() und io_submit(). Insbesondere sind die von Peter angegebenen „aio_“-Funktionen Teil der glibc-Emulation auf Benutzerebene, die auf Threads basiert, was nicht der Fall ist eine effiziente Implementierung. Die eigentliche Antwort lautet:
io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)
Beachten Sie, dass die Manpage vom 2012-08 besagt, dass diese Implementierung noch nicht so weit ausgereift ist, dass sie die Glibc-User-Space-Emulation ersetzen kann:
http://man7.org/linux/man-pages/man7/aio.7.html
diese Implementierung ist noch nicht soweit ausgereift, dass die POSIXAIO-Implementierung vollständig neu implementiert werden kann, indem die Kernelsystem-Aufrufe verwendet werden.
Laut der neuesten Kernel-Dokumentation, die ich finden kann, hat Linux noch kein ausgereiftes, Kernel-basiertes asynchrones I/O-Modell. Und wenn ich davon ausgehe, dass das dokumentierte Modell tatsächlich ausgereift ist, unterstützt es immer noch keine partielle I/O im Sinne von recv() vs. read().