it-swarm.com.de

Welche Philosophie steckt dahinter, das Schreiben von Daten auf die Festplatte zu verzögern?

Unter Linux bedeutet eine abgeschlossene Ausführung eines Befehls wie cp oder dd nicht, dass die Daten auf das Gerät geschrieben wurden. Man muss zum Beispiel sync aufrufen oder die Funktion "Sicher entfernen" oder "Auswerfen" auf dem Laufwerk aufrufen.

Welche Philosophie steckt hinter einem solchen Ansatz? Warum werden die Daten nicht sofort geschrieben? Besteht keine Gefahr, dass der Schreibvorgang aufgrund eines E/A-Fehlers fehlschlägt?

72
marmistrz

Welche Philosophie steckt hinter einem solchen Ansatz?

Effizienz (bessere Nutzung der Festplatteneigenschaften) und Leistung (ermöglicht es der Anwendung, unmittelbar nach dem Schreiben fortzufahren).

Warum werden die Daten nicht sofort geschrieben?

Der Hauptvorteil besteht darin, dass das Betriebssystem zusammenhängende Schreibvorgänge neu anordnen und zusammenführen kann, um die Bandbreitennutzung zu verbessern (weniger Vorgänge und weniger Suchvorgänge). Festplatten weisen eine bessere Leistung auf, wenn eine kleine Anzahl großer Vorgänge angefordert wird, während Anwendungen stattdessen eine große Anzahl kleiner Vorgänge benötigen. Eine weitere klare Optimierung ist, dass das Betriebssystem auch alle bis auf den letzten Schreibvorgang entfernen kann, wenn derselbe Block in kurzer Zeit mehrmals geschrieben wurde, oder sogar einige Schreibvorgänge alle zusammen entfernen kann, wenn die betroffene Datei in der Zwischenzeit entfernt wurde.

Diese asynchronen Schreibvorgänge werden ausgeführt nach der Systemaufruf write ist zurückgekehrt. Dies ist der zweite und am meisten vom Benutzer sichtbare Vorteil. Asynchrone Schreibvorgänge beschleunigen die Anwendungen, da sie ihre Arbeit fortsetzen können, ohne darauf zu warten, dass sich die Daten tatsächlich auf der Festplatte befinden. Die gleiche Art des Pufferns/Zwischenspeicherns wird auch für Lesevorgänge implementiert, bei denen kürzlich oder häufig gelesene Blöcke im Speicher verbleiben, anstatt erneut von der Festplatte gelesen zu werden.

Besteht keine Gefahr, dass der Schreibvorgang aufgrund eines Fehlers IO) fehlschlägt?

Nicht unbedingt. Dies hängt vom verwendeten Dateisystem und der vorhandenen Redundanz ab. Ein E/A-Fehler kann harmlos sein, wenn die Daten an anderer Stelle gespeichert werden können. Moderne Dateisysteme wie ZFS heilen fehlerhafte Festplattenblöcke selbst. Beachten Sie auch, dass E/A-Fehler moderne Betriebssysteme nicht zum Absturz bringen. Wenn sie während des Datenzugriffs auftreten, werden sie einfach an die betroffene Anwendung gemeldet. Wenn sie während des Zugriffs auf strukturelle Metadaten auftreten und das Dateisystem gefährden, kann es schreibgeschützt erneut bereitgestellt oder unzugänglich gemacht werden.

Es besteht auch ein geringes Datenverlustrisiko bei einem Betriebssystemabsturz, einem Stromausfall oder einem Hardwarefehler. Dies ist der Grund, warum Anwendungen, die zu 100% sicher sein müssen, dass sich die Daten auf der Festplatte befinden (z. B. Datenbanken/Finanzanwendungen), weniger effiziente, aber sicherere synchrone Schreibvorgänge ausführen. Um die Auswirkungen auf die Leistung zu verringern, verwenden viele Anwendungen immer noch asynchrone Schreibvorgänge, synchronisieren sie jedoch schließlich, wenn der Benutzer eine Datei explizit speichert (z. B. vim, Textverarbeitungsprogramme).

Andererseits benötigt oder kümmert sich eine sehr große Mehrheit der Benutzer und Anwendungen nicht um die Sicherheit, die synchrone Schreibvorgänge bieten. Bei einem Absturz oder Stromausfall besteht das einzige Risiko häufig darin, im schlimmsten Fall die letzten 30 Sekunden an Daten zu verlieren. Sofern es sich nicht um eine Finanztransaktion oder ähnliches handelt, die Kosten verursachen würde, die viel länger als 30 Sekunden ihrer Zeit sind, lässt der enorme Leistungsgewinn (der keine Illusion, aber sehr real ist) bei asynchronen Schreibvorgängen das Risiko weitgehend hinter sich.

Schließlich reichen synchrone Schreibvorgänge ohnehin nicht aus, um die geschriebenen Daten zu schützen. Wenn Ihre Anwendung wirklich sicherstellen muss, dass ihre Daten nicht verloren gehen können, muss die Datenreplikation auf mehreren Festplatten und an mehreren geografischen Standorten eingerichtet werden, um Katastrophen wie Feuer, Überschwemmungen usw. zu widerstehen.

47
jlliagre

Es gibt Programmen, die nicht wirklich warten müssen, bis ein Schreibvorgang abgeschlossen ist, einfach eine Illusion von Geschwindigkeit. Hängen Sie Ihre Dateisysteme im Synchronisierungsmodus ein (wodurch Sie sofort schreiben können) und sehen Sie, wie langsam alles ist.

Manchmal existieren Dateien nur vorübergehend ... ein Programm erledigt einige Arbeiten und löscht die Datei direkt nach Abschluss der Arbeiten. Wenn Sie diese Schreibvorgänge verzögert haben, könnten Sie davonkommen, dass Sie sie überhaupt nicht geschrieben haben.

Besteht keine Gefahr, dass der Schreibvorgang aufgrund eines Fehlers IO) fehlschlägt?

Oh, absolut. In einem solchen Fall geht normalerweise das gesamte Dateisystem in den schreibgeschützten Modus und alles ist schrecklich. Dies kommt jedoch selten vor, und es macht keinen Sinn, die Leistungsvorteile im Allgemeinen zu verlieren.

59
frostschutz

Asynchrone, gepufferte E/A wurden vor Linux und sogar vor Unix verwendet. Unix hatte es und so haben alle seine Ableger.

Folgendes haben Ritchie und Thompson in ihrem CACM-Artikel geschrieben The UNIX Time-Sharing System :

Für den Benutzer scheinen sowohl das Lesen als auch das Schreiben von Dateien synchron und ungepuffert zu sein. Das heißt, unmittelbar nach der Rückkehr von einem Leseaufruf sind die Daten verfügbar, und umgekehrt kann der Arbeitsbereich des Benutzers nach einem Schreibvorgang wiederverwendet werden. Tatsächlich unterhält das System einen ziemlich komplizierten Puffermechanismus, der die Anzahl der E/A-Operationen, die für den Zugriff auf eine Datei erforderlich sind, erheblich reduziert.


In Ihrer Frage haben Sie auch geschrieben:

Besteht keine Gefahr, dass der Schreibvorgang aufgrund eines Fehlers IO) fehlschlägt?

Ja, das Schreiben kann fehlschlagen und das Programm weiß möglicherweise nie davon. Obwohl dies nie gut ist, können die Auswirkungen in Fällen minimiert werden, in denen ein E/A-Fehler eine Systempanik auslöst (auf einigen Betriebssystemen ist dies konfigurierbar - anstatt in Panik zu geraten, kann das System weiterhin ausgeführt werden, das betroffene Dateisystem jedoch unmontiert oder schreibgeschützt montiert). Benutzer können dann benachrichtigt werden, dass die Daten in diesem Dateisystem verdächtig sind. Ein Festplattenlaufwerk kann proaktiv überwacht werden, um festzustellen, ob seine gewachsene Fehlerliste schnell ansteigt, was ein Hinweis darauf ist, dass das Laufwerk ausfällt.

BSD hat den Systemaufruf fsync hinzugefügt, damit ein Programm sicher sein kann, dass seine Dateidaten vollständig auf die Festplatte geschrieben wurden, bevor es fortfährt, und nachfolgende Unix-Systeme Optionen für synchrone Schreibvorgänge bereitgestellt haben . GNU dd hat eine Option conv=fsync, um sicherzustellen, dass alle Daten ausgeschrieben wurden, bevor der Befehl beendet wird. Dies ist praktisch, wenn Sie auf langsame Wechseldatenträger schreiben, bei denen das Schreiben gepufferter Daten einige Minuten dauern kann.

Eine weitere Ursache für Dateibeschädigungen ist ein plötzliches Herunterfahren des Systems, beispielsweise aufgrund eines Stromausfalls. Praktisch alle aktuellen Systeme unterstützen ein Clean/Dirty - Flag in ihren Dateisystemen. Das Flag wird auf clean gesetzt, wenn keine Daten mehr ausgeschrieben werden müssen und das Dateisystem kurz vor dem Aushängen steht, normalerweise während des Herunterfahrens des Systems oder manuell Aufruf von umount. Systeme werden normalerweise beim Neustart fsck ausgeführt, wenn sie feststellen, dass Dateisysteme nicht ordnungsgemäß heruntergefahren wurden.

26
Mark Plotnick

Viele gute Antworten, aber lassen Sie mich noch etwas hinzufügen ... Denken Sie daran, dass Unix ein System mit mehreren Prozessen und mehreren Benutzern ist, sodass möglicherweise viele Benutzer versuchen würden, Dateivorgänge (insbesondere Schreibvorgänge) bei (fast) dem auszuführen gleiche Zeit. Bei alten langsamen Festplatten - möglicherweise über das Netzwerk bereitgestellt - würde dies nicht nur Zeit in Anspruch nehmen (auf die die Programme im Grunde genommen abstürzen würden und die Benutzer warten müssen), sondern auch viel Bewegung des Lese-/Schreibkopfs des Scheibe hin und her.

Stattdessen wurden die Dateien, die darauf warteten, geschrieben zu werden, eine Weile im Speicher gespeichert und sortiert danach, wo sie auf der Festplatte landen sollten ... und wann der Puffer voll war - oder auf der Festplatte -sync Daemon hatte auf die erforderliche Anzahl von Sekunden gewartet (ich glaube, es waren normalerweise ungefähr 30 Sekunden) - der gesamte Puffer wurde "in der richtigen Reihenfolge" auf die Festplatte geschrieben, wobei der Schreibkopf nur eine kontinuierliche Wobbelbewegung ausführen musste. Schreiben Sie die Dateien im Laufe der Zeit auf die Festplatte ... anstatt überall herumzuspringen.

Natürlich ist der Gewinn bei heutigen schnellen Festplatten - ganz zu schweigen von Solid-State-Geräten - viel geringer ... insbesondere bei einem Heim-Linux-System, bei dem jeweils nur ein Benutzer und nur wenige Programme gleichzeitig arbeiten.

Wie auch immer, die Kombination aus Vorwegnahme von Lesevorgängen durch Einlesen (in den Cache/Puffer) mehr als gewünscht - und Sortieren von Daten, die darauf warten, geschrieben zu werden, damit sie in "einer Bewegung" geschrieben werden können - war tatsächlich eine sehr gute Idee Zeit, insbesondere auf Systemen mit viel Lesen und Schreiben durch viele Benutzer.

15
Baard Kopperud

Es ist nicht spezifisch für Linux und heißt Seiten-Cache (was Linux recht gut kann). Siehe auch http://linuxatemyram.com/ ; Wenn also eine Datei geschrieben und einige Sekunden später erneut gelesen wird, sind sehr oft keine Festplatten-E/A erforderlich.

Der Hauptvorteil besteht darin, dass auf vielen Systemen viel RAM vorhanden ist und ein Teil davon vom Kernel als Cache verwendet werden kann. Einige Dateivorgänge können also von diesem Caching profitieren. Außerdem ist die E/A-Zeit der Festplatte viel langsamer (normalerweise viele tausend Mal für SDD und fast eine Million Mal langsamer für mechanische Festplatten) als RAM.

Der Anwendungscode kann Hinweise zu diesem Caching geben: siehe z. posix_fadvise (2) & madvise (2)

13

Drehplatten sind langsamer als RAM. Wir verwenden das Caching von Lese-/Schreibvorgängen, um diese Tatsache zu "verbergen".

Das Nützliche an write IO ist, dass keine Festplatte erforderlich ist IO muss sofort erfolgen - im Gegensatz zu einem Lesevorgang, bei dem Sie keine Daten an das zurückgeben können Benutzer, bis der Lesevorgang auf der Festplatte abgeschlossen ist.

Schreibvorgänge werden daher unter zeitlichen Einschränkungen ausgeführt. Solange unser anhaltender Durchsatz den unserer Festplatte nicht überschreitet, können wir viele Leistungseinbußen in einem Schreibcache verbergen.

Und wir müssen Cache schreiben - sich drehende Festplatten sind vergleichsweise sehr langsam. Moderne RAID-Typen haben jedoch erhebliche Nachteile für den Betrieb.

Ein RAID 6 zum Beispiel, um einen Schreibvorgang abzuschließen IO muss:

  • Update-Block lesen
  • parität lesen1
  • parität 2 lesen
  • schreibe einen neuen Block
  • schreibe Parität 1
  • schreibe Parität 2

Somit ist jeder Schreibvorgang tatsächlich 6 IO Operationen) - und insbesondere wenn Sie langsame Festplatten wie große SATA-Laufwerke haben, wird dies extrem teuer.

Aber es gibt eine schöne einfache Lösung - das Zusammenführen von Texten. Wenn Sie einen 'Full Stripe'-Schreibvorgang in einem Puffer erstellen können, müssen Sie die Parität nicht von Ihrer Festplatte lesen - Sie können sie basierend auf dem, was Sie im Speicher haben, berechnen.

Dies ist sehr wünschenswert, da Sie dann keine Schreibverstärkung mehr haben. In der Tat können Sie mit einer geringeren Schreibstrafe als RAID 1 + 0 enden.

Erwägen:

RAID 6, 8 + 2 - 10 Spindeln.

8 aufeinanderfolgende Datenblöcke zum Schreiben - Berechnen Sie die Parität im Cache und schreiben Sie einen Block auf jede Festplatte. 10 Schreibvorgänge pro 8 bedeuten eine Schreibstrafe von 1,25. 10 Festplatten von RAID 1 + 0 haben immer noch eine Schreibstrafe von 2 (weil Sie auf jeden Subspiegel schreiben müssen). In diesem Szenario können Sie also die Leistung von RAID 6 verbessern als RAID1 + 0. In der realen Welt erhalten Sie jedoch eher ein gemischtes IO -Profil).

Das Zwischenspeichern von Schreibvorgängen hat also einen großen Einfluss auf die wahrgenommene Leistung von RAID-Sets. Sie können mit einer Geschwindigkeit von RAM) schreiben und haben eine geringe Schreibstrafe - und verbessern so Ihren anhaltenden Durchsatz, wenn Sie dies tun.

Und wenn Sie dies nicht tun, leiden Sie unter der schmerzhaften langsamen Leistung von SATA, aber multiplizieren Sie sie mit 6 und fügen Sie dort einige Konflikte hinzu. Ihr 10-Wege-SATA-RAID-6 ohne Schreib-Caching wäre etwas schneller als ein einzelnes Laufwerk ohne RAID ... aber nicht sehr viel.

Sie gehen jedoch ein Risiko ein - wie Sie bemerken - bedeutet Stromausfall Datenverlust. Sie können dies abmildern, indem Sie die Cache leeren, den Cache mit einem Akku sichern oder SSD oder andere nichtflüchtige Caches verwenden.

8
Sobrique

Keine der anderen genannten Antworten verzögerte Zuweisung . XFS, ext4, BTRFS und ZFS verwenden es alle. XFS verwendet es seit der Existenz von ext4, daher verwende ich es als Beispiel:

XFS entscheidet erst beim Ausschreiben, wo Daten abgelegt werden sollen. Delayed-Allocation gibt dem Allokator viel mehr Informationen, auf die er seine Entscheidungen stützen kann. Wenn eine Datei zum ersten Mal geschrieben wird, kann nicht festgestellt werden, ob es sich um eine 4k-Datei oder eine 1G-Datei handelt, die noch wächst. Wenn irgendwo 10 G zusammenhängender freier Speicherplatz vorhanden sind, hilft es nicht, die 4k-Datei am Anfang zu platzieren. Wenn Sie die große Datei am Anfang eines großen freien Speicherplatzes platzieren, wird die Fragmentierung verringert.

7
Peter Cordes

Alle anderen Antworten hier sind mindestens für den Normalfall meistens korrekt, und ich würde empfehlen, eine davon vor meiner zu lesen, aber Sie haben erwähnt, dass dd und dd einen typischen Anwendungsfall haben, bei dem möglicherweise kein Schreib-Caching erforderlich ist. Das Schreib-Caching wird hauptsächlich auf Dateisystemebene implementiert. Raw-Geräte schreiben normalerweise kein Caching (mehrere Gerätetreiber wie raid oder lvm sind ein weiterer Wachsball). Da dd häufig mit Raw-Block-Geräten verwendet wird, bietet es das bs und die zugehörigen Optionen, um große Schreibvorgänge für eine bessere Leistung auf Raw-Geräten zu ermöglichen. Dies ist nicht so nützlich, wenn beide Endpunkte reguläre Dateien sind (obwohl große Schreibvorgänge in diesem Fall weniger Systemaufrufe erfordern). Der andere häufige Ort, an dem dies besonders sichtbar ist, ist das mtools-Paket, bei dem es sich um eine Implementierung des Fat-Dateisystems im Userspace handelt. Die Verwendung von mtools mit einem Diskettenlaufwerk fühlt sich immer unglaublich träge an, da die Tools vollständig synchron sind und Diskettenlaufwerke unglaublich langsam sind. Das Mounten der Diskette und das Verwenden des Kernel-Fat-Dateisystems ist viel reaktionsschneller, mit Ausnahme von umount, das synchron ist (und sehr wichtig, damit Datenverluste vermieden werden, insbesondere bei Wechseldatenträgern wie Disketten). Es gibt nur wenige andere Programme, von denen ich weiß, dass sie regelmäßig mit Raw-Geräten wie speziell konfigurierten Datenbanken (die ihr eigenes Schreib-Caching implementieren), tar sowie speziellen Geräte- und Dateisystem-Tools wie chdsk, mkfs und mt verwendet werden.

4
hildred

Die Philosophie ist standardmäßig unsicher.

Es sind zwei vernünftige und offensichtliche Strategien möglich: Schreiben sofort auf die Festplatte leeren oder Schreiben verzögern. UNIX hat sich historisch für Letzteres entschieden. Um sich in Sicherheit zu bringen, müssen Sie anschließend fsync aufrufen.

Sie können die Sicherheit jedoch im Voraus festlegen, indem Sie ein Gerät mit der Option sync mounten, oder per Datei, indem Sie sie mit O_SYNC Öffnen.

Denken Sie daran, dass UNIX für Computerexperten entwickelt wurde. "Standardmäßig sicher" war keine Überlegung. Sicherheit bedeutet langsamere E/A, und diese frühen Systeme hatten wirklich langsame E/A, was den Preis hoch erhöhte. Leider haben weder UNIX noch Linux auf Safe-Be-Default umgestellt, obwohl dies eine nicht brechende Änderung ist.

3
MSalters

Es tauscht ein geringes Maß an Zuverlässigkeit gegen eine große Steigerung des Durchsatzes.

Angenommen, beispielsweise ein Videokomprimierungsprogramm. Mit verzögertem Schreiben ("Rückschreiben"):

  1. verbringen Sie 10 ms beim Komprimieren des Rahmens
  2. schreibrahmen auf Festplatte ausgeben
  3. warten Sie 10 ms, bis die Festplatte bestätigt, dass der Schreibvorgang abgeschlossen ist
  4. GOTO 1

Versus

  1. verbringen Sie 10 ms beim Komprimieren des Rahmens
  2. schreibrahmen auf Festplatte ausgeben (wird im Hintergrund abgeschlossen)
  3. GOTO 1

Die zweite Version erscheint doppelt so schnell, da sie die CPU und die Festplatte gleichzeitig verwenden kann, während die erste Version immer auf die eine oder andere wartet.

Im Allgemeinen möchten Sie ein Zurückschreiben für Streaming-Vorgänge und Massendateivorgänge sowie ein Durchschreiben für Datenbanken und datenbankähnliche Anwendungen.

2
pjc50

In vielen Anwendungen sind Speichergeräte zeitweise mit dem Lesen von Daten beschäftigt. Wenn ein System Schreibvorgänge immer so lange verschieben kann, bis das Speichergerät nicht mehr mit dem Lesen von Daten beschäftigt ist, dauert es aus Sicht einer Anwendung null Zeit, bis die Schreibvorgänge abgeschlossen sind. Die einzigen Situationen, in denen das Schreiben nicht sofort erfolgt, sind:

  1. Schreibpuffer füllen sich bis zu dem Punkt, an dem keine verzögerten Schreibanforderungen mehr akzeptiert werden können, bis die Schreibvorgänge tatsächlich abgeschlossen sind.

  2. Das Gerät, für das Schreibvorgänge anstehen, muss heruntergefahren oder entfernt werden.

  3. Eine Anwendung fordert ausdrücklich die Bestätigung an, dass ein Schreibvorgang tatsächlich abgeschlossen ist.

In der Tat ist es nur aufgrund der oben genannten Anforderungen, dass Schreibvorgänge überhaupt jemals stattfinden müssen. Auf der anderen Seite gibt es im Allgemeinen keinen Grund, ausstehende Schreibvorgänge zu Zeiten nicht auszuführen, in denen ein Gerät ansonsten inaktiv wäre. Daher führen viele Systeme diese dann aus.

1
supercat

Es gibt auch das:

Schreiben Sie "Hi, Joe Moe"
ist schneller als:
Schreiben Sie "Hallo"
Schreiben Sie "Joe"
Schreiben Sie "Moe"

Und auch:

Schreiben Sie "Hallo, wie geht es Ihnen?"
ist schneller als:
Schreiben Sie "Hallo, was ist los?"
Lösch das
Schreiben Sie "Grüß dich, wie geht es dir?"
Lösch das
Schreiben Sie "Hallo, wie geht es Ihnen?"

Es ist besser, wenn Änderungen und Aggregationen in RAM] als auf der Festplatte erfolgen. Durch das Batching von Festplattenschreibvorgängen werden Anwendungsentwickler von solchen Bedenken befreit.

0
Rolf