GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Gibt es unter Linux wirklich keine asynchrone Block-I/O?

(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 (zB fsync (>=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 zum libaio 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 gibt io_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 zu io_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, das threads übertrifft und aio 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 den io_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 von io_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 optionalen io_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 PostgreSQL io_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 den liburing 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 Distribution liburing nicht vorkonfiguriert .
  • Der anfängliche Kernel von Fedora 32 ist 5.6 und es hat einen verpackten liburing also io_uring nutzbar ist.
  • SLES 15 SP2 hat einen 5.3-Kernel, also io_uring Systemaufrufe können verwendet werden. Diese Distribution enthält den liburing 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ür io_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().


Linux
  1. Linux – Wie überwacht man die Festplatten-E/A in einem bestimmten Verzeichnis?

  2. Verwirrung über den internen asynchronen I/O-Mechanismus von node.js

  3. Linux:Gibt es etwas ähnliches wie top für I/O?

  4. Debuggen der Linux-I/O-Latenz

  5. Gibt es eine Möglichkeit, LD_PRELOAD und LD_LIBRARY_PATH unter Linux zu blockieren?

10 Linux iostat Befehl zum Melden von CPU- und E/A-Statistiken

10 iozone-Beispiele für die Messung der Festplatten-E/A-Leistung unter Linux

Wie lösche ich Festplatten-E/A-Caches unter Linux?

Was ist das Unix/Linux-Äquivalent von Registered I/O?

E/A-Fehler unter Linux:Verzeichnis kann nicht als Root entfernt werden

Massiver, unvorhersehbarer I/O-Leistungsabfall in Linux