Verwendung von O_DIRECT unter Linux

23

Wenn diese Frage zu programmiererorientiert ist, lassen Sie es mich wissen. Ich frage mich, ob es Leute gibt, die mit dem O_DIRECT-Flag für den open () -Systemaufruf unter Linux 2.6 vertraut sind. Linus lehnt seine Verwendung ab, jedoch scheint das Schreiben von Dateien mit hoher Leistung auf seine Verwendung hinzudeuten. Ich würde gerne etwas über Erfahrungen und Empfehlungen aus der realen Welt erfahren.

Weitere Informationen: Die Anwendung, die ich verwende , verwaltet einen eigenen Cache und erreicht dadurch eine durchschnittlich 5-fache oder höhere Geschwindigkeit. Beim Schreiben in eine Datei muss der Inhalt des Caches in den Dateisystem-Cache geschrieben werden. Dies scheint redundant und ein Leistungsproblem zu sein.

casualunixer
quelle

Antworten:

17

Ok, du fragst nach Erfahrungen, das macht die Frage etwas subjektiv und argumentativ, aber passabel.

Linus sagte, dass mit Bezug auf die Verwendungen, die die Leute normalerweise O_DIRECT zuschreiben, und für diese Verwendungen IMO Linus meistens richtig ist. Auch wenn Sie direkte E / A-Vorgänge ausführen, können Sie keine Daten von / zu Geräten direkt in Ihre Programmanweisungen übertragen. Sie benötigen einen Puffer, der (vom Programm oder vom Gerät) gefüllt und über einen Systemaufruf an das andere Ende übertragen wird. Um es effizienter zu gestalten, sollten Sie nicht noch einmal etwas lesen, das Sie gerade gelesen haben, falls Sie es erneut benötigen. Sie brauchen also eine Art Cache ... und genau das bietet der Kernel ohne O_DIRECT, einen Seiten-Cache! Warum nicht das benutzen? Es hat auch Vorteile, wenn mehrere Prozesse gleichzeitig auf dieselbe Datei zugreifen möchten. Dies wäre mit O_DIRECT eine Katastrophe.

Allerdings hat O_DIRECT seine Verwendung: Wenn Sie aus irgendeinem Grund Daten direkt vom Blockgerät abrufen müssen. Es hat nichts mit Leistung zu tun.

Leute, die O_DIRECT für die Leistung verwenden, kommen normalerweise von Systemen mit schlechten Page-Cache-Algorithmen oder ohne POSIX-Hinweismechanismen oder sogar von Leuten, die gedankenlos wiederholen, was andere Leute gesagt haben. Um diese Probleme zu vermeiden, war O_DIRECT eine Lösung. Linux, OTOH, hat die Philosophie, dass Sie das eigentliche zugrunde liegende Problem beheben sollten, und das zugrunde liegende Problem waren Betriebssysteme, die beim Seiten-Caching schlechte Arbeit geleistet haben.

Ich habe O_DIRECT für eine einfache Implementierung von cat verwendet, um einen Speicherfehler in meinem Computer zu finden. Dies ist eine gültige Verwendung für O_DIRECT. Das hatte nichts mit Leistung zu tun.

Juliano
quelle
Vielen Dank für die Info, es wird geschätzt. Ich habe meine Frage mit den spezifischen Bedingungen der App aktualisiert, die zu dieser Frage geführt haben. Wenn Sie weitere Informationen zu den POSIX-Hinweismechanismen für das Schreiben von Dateien haben, wären Sie auch dafür dankbar.
Casualunixer
4
o_direct kann auch in einem System nützlich sein, in dem der Entwickler einen Caching-Mechanismus auf Anwendungsebene bereitstellen möchte (think database).
Jmoney38
Es hat nichts mit Leistung zu tun. Dies gilt nicht immer, insbesondere für den Zugriff auf ein Hochgeschwindigkeitsgerät, bei dem die E / A-Raten der Speicherbandbreite oder sogar nur einem signifikanten Prozentsatz der Speicherbandbreite entsprechen. In diesem Fall kann das Überspringen der zusätzlichen Kopie zum / vom Seiten-Cache erhebliche Leistungsvorteile haben.
Andrew Henle
13

Eigentlich muss O_DIRECT man beides vermeiden

  • Cacheverschmutzung - manchmal wissen Sie, dass Caching keinen Sinn macht, z. B. wenn es sich um sehr große Dateien handelt, sagen wir 64 GiB, wenn nur 2 GiB RAM vorhanden sind. Torrent-Datei von 32 GiB, die ein Benutzer überprüft hat, scheint kein guter Kandidat für das Caching zu sein. Es ist nur zusätzliche Aktivität mit eigenem Overhead. Und es kann dazu führen, dass einige wirklich nützliche Daten aus dem Cache entfernt werden.
  • Doppelte Zwischenspeicherung - für einige RDBMS (MySQL zu erwähnen) können Sie beispielsweise einen eigenen Cache definieren. Angeblich wissen Datenbanken besser, wie und was zwischengespeichert wird, als der virtuelle Speicher des Kernels, der nichts über SQL-Planung usw. weiß.

- was anscheinend nicht gut ist. Und O_DIRECTheißt nicht, schneller zu sein, oft auch nicht .

Poige
quelle
10
posix_fadvisekann sich um das Cache-Verschmutzungsproblem kümmern.
Psusi
Ich glaube nicht, dass der virtuelle Speicher irgendetwas damit zu tun hat, er ordnet lediglich die Speicheradresse zu. Buffer Cache / Page Cache ist das, was Sie meinen.
ArekBulski
Caches / Caching ist ein Teil des VM-Subsystems unter UNIX, soweit ich das beurteilen kann. Deshalb habe ich diesen Begriff verwendet. Danke für die Bearbeitung. :)
Poige
6

Beachten Sie, dass die Verwendung O_DIRECTin neueren Kerneln mit neueren Dateisystemen möglicherweise fehlschlägt. Siehe diesen Fehlerbericht zum Beispiel. Daher ist die Verwendung nicht nur oft zweifelhaft, sondern wird in der kommenden Generation von Linux-Distributionen wahrscheinlich überhaupt nicht funktionieren. Daher würde ich die Leistung meines Codes nicht darauf wetten, selbst wenn Sie nachweisen könnten, dass er einen Vorteil hat.

Peter Eisentraut
quelle
1
Der Fehlerbericht beschreibt tatsächlich die Verwendung von Dateisystemen mit aktivierter Option journal = data. Diese Option steht in direktem Gegensatz zum O_DIRECT-Flag. Bei den meisten ext3- und ext4-Dateisystemen ist dieses Flag nicht gesetzt. Wenn Sie es deaktivieren, können Sie die Datei mit O_DIRECT öffnen.
casualunixer
3

Es hat viel mit Leistung zu tun.

Ein interessantes Beispiel ist Mongodb mit der MMAP-Engine. O_DIRECT wird am besten verwendet, wie andere angegeben haben, wenn es unwahrscheinlich ist, dass die Daten für einige Zeit gelesen werden. In mongodb wird das Datenbankjournal mit O_DIRECT geschrieben, während die Daten- und Indexschreibvorgänge vom Seiten-Cache-Mechanismus (pdflush) verarbeitet werden, da O_DIRECT zwar weniger Bandbreite bietet, aber auch eine geringere Latenz bedeutet und somit den Datenverlust im Falle eines unerwarteter Ausfall (Kernel-Panik, Festplatten- oder Stromausfall). Beachten Sie, dass vor dem Festschreiben eines O_DIRECT-Schreibvorgangs in einen nichtflüchtigen Speicher noch ein Puffer vorhanden ist. Dies reduziert lediglich den Datenverlust.

Ein weiteres wichtiges Merkmal von O_DIRECT ist, dass es mehr Kontrolle über die Reihenfolge der Schreibvorgänge bietet . Auch hier wird die Reihenfolge der Schreibvorgänge nicht garantiert (es sei denn, Sie verfügen über einen nichtflüchtigen Caching-Festplattencontroller und verwenden den FIFO-Scheduler, diese haben jedoch ihre eigenen Komplikationen). Obwohl mysql O_DIRECT für seine Daten / Indizes sowie das Journalling verwendet, kann erwartet werden, dass letzteres normalerweise zuerst festgeschrieben wird.

Es ist jedoch wichtig, sich daran zu erinnern, dass O_DIRECT die Fairness bei der Ressourcenzuteilung verletzt. Einer der Gründe, warum Ihre Anwendung beschleunigt wird, ist, dass sie andere Dinge verlangsamt.

symcbean
quelle
Sie sagen, es hat viel mit der Leistung zu tun, aber Sie geben ein Beispiel, in dem es entweder zum Verringern der Latenz oder zum Ordnen von Schreibvorgängen verwendet wird. Ich stimme jedoch zu, dass dies die Leistung beeinträchtigt. Fair Point über Fairness.
ArekBulski
Können Sie weitere Referenzen angeben, um zu erklären, wenn es unfair ist?
ACyclic
3

In Bezug auf das, was @ Juliano bereits gesagt hat.

Überprüfen Sie, posix_fadviseob das eigentliche Problem ein Fehlverhalten des Cache-Algorithmus des zugrunde liegenden Dateisystems ist. Sie können versuchen, ihm Ratschläge zu geben, wie Sie das Dateisystem verwenden. Für gut implementierte fs sollte es einen Leistungsschub geben. (Hier ist ein Link zu einem anderen Thema mit ähnlichen Überlegungen: /programming//a/3755818/544721 )

Grzegorz Wierzowiecki
quelle
1
Es sieht so aus, als ob posix_fadvise die vom Kernel verwendeten Readahead-Algorithmen ändert. Der entscheidende Faktor für den fraglichen Code ist die Schreibleistung. Das Problem ist, dass das Schreiben des Puffers zuerst die Linux-Caches füllt, die der Kernel dann ausgeben muss, wenn ihm der Speicher ausgeht. Dies ist eine Verschwendung von Aufwand, die Ausgabe sollte in diesem Fall auf dem Weg zur Festplatte minimal gepuffert werden.
Casualunixer