Was ist falsch an Copy-on-Write für Linux beim Kopieren?



Warnung: Dieser Artikel gilt für alle CoW-Dateisysteme unter Linux, die beim Kopieren ein Reflink unterstützen. Im Moment sind dies: BTRFS, XFS und OCFS2.

Bitte verzichten Sie auf Holivars, bei denen FS besser ist: Btrfs, XFS, Reiser4, NILFS2, ZFS oder einige nicht erwähnte.

Hintergrund


  • 21. Juli 2001 - Namesys veröffentlicht die Ankündigung von Reiser4 . DARPA sponsert die Entwicklung.
  • 20. November 2003 - Namesys veröffentlicht einige Reiser4-Benchmarks .
  • 24. August 2004 - Namesys veröffentlicht Reiser4 öffentlich.
  • 14. September 2004 - Ankündigung des ZFS.
  • 16. November 2005 - ZFS ist in OpenSolaris Build 27 enthalten.
  • September 2006 - Hans Reiser wegen Mordes an Frau Nina Reiser verhaftet. Anfang vom Ende von Namesys
  • 12. Juni 2007 - Btrfs Ankündigung von Chris Mason (ehemaliger Mitarbeiter von Namesys).
  • 22. September 2011 - In ZFSonLinux wurde ein Ticket mit einer Anfrage zur Reflink-Implementierung angezeigt.
  • 2012 - Btrfs als stabiles Oracle Linux und SUSE Linux Enterprise anerkannt
  • 21. Januar 2013 - Das Experiment-Label wurde mit Btrfs im Quellcode des Linux-Kernels entfernt.
  • Mai 2019 - Btrfs aus RHEL 8 entfernt (versteckte politische Gründe, die als von Oracle geförderte Btrfs vermutet werden)

Kopieren Sie die Erwartungen in CoW-Dateisystemen


Als Reiser4 im Jahr 2001 angekündigt wurde, war ich von Copy-on-Write begeistert und begeistert. Denken Sie nur, wir können einfach und einfach so viele Kopien verschiedener Projekte haben, wie Sie möchten, und auf der Festplatte werden nur Unterschiede zwischen ihnen gespeichert!

Außerdem sollte die Kopiergeschwindigkeit unangemessen steigen. Aufgrund der Tatsache, dass beim Kopieren nur ein Reflink-Link zur alten Datei erstellt wird. Beim Schreiben in eine solche neue Datei werden Sektoren für geänderte Daten automatisch zugewiesen. Infolgedessen hätten wir die gleichen Sektoren für die gemeinsamen Teile der Dateien, und verschiedene Teile würden in verschiedenen Sektoren aufgezeichnet.

Es sah damals wie ein Allheilmittel für die Erstellung von Konten für Shared Hosting aus und ist jetzt die beste Lösung für leichte virtuelle Maschinen und Container. Schließlich konnten wir keinen Speicherplatz für identische Dateien verschwenden und gleichzeitig den Benutzern das einfache Ändern dieser Dateien ermöglichen.

Hans Riser ging jedoch auf das Dach und tötete seine Frau, und seine Idee (höchstwahrscheinlich aus politischen Gründen) war nicht im Kern enthalten. Vielleicht hängt die Geschichte doch von einer bestimmten Person ab?

ZFS wurde unter einer mit Linux nicht kompatiblen Lizenz veröffentlicht und war daher nicht im Kernel enthalten. Daher wurde die Einführung von ZFS unter Linux lange Zeit verlangsamt.

Danach fing ich an, auf Btrfs zu warten. Und nur 6 Jahre nach der Ankündigung wurde es von den Entwicklern des Linux-Kernels als stabil erkannt.

Danach hatte ich es nicht eilig, Cow-Systeme zu verwenden, da das Copy-on-Write-Paradigma selbst eine erhöhte Fragmentierung impliziert, da Datenänderungen jedes Mal an einen neuen Ort geschrieben werden.

Bei Festplatten beeinträchtigt die Fragmentierung die Leistung, da das Neupositionieren des Blocks der Leseköpfe sehr langwierig ist.

Daher habe ich persönlich die Implementierung von btrfs auf meinen Computern verschoben, bis sie auf SSD umgestellt haben.

Ich stelle fest, dass SSDs auch keine Fragmentierung mögen. Jeder weiß, dass lineares Schreiben / Lesen bei einer SSD zehnmal schneller sein kann als der Direktzugriff.

Die Leistung einer fragmentierten SSD ist jedoch nicht so dramatisch wie die einer Festplatte.

Was ist also mit der Kopiergeschwindigkeit mit CoW?


Und schließlich ist die Zeit gekommen. Als SSDs zuverlässig genug wurden, begann ich, CoW-Dateisysteme mit Macht und Kraft zu verwenden. Insbesondere Btrfs und Nilfs2.

Als ich die aufregenden Möglichkeiten von Schnappschüssen beherrschte, vergaß ich für eine Weile meine Erwartungen aus den 2000er Jahren an das ultraschnelle Kopieren von Dateien.

Nach einiger Zeit beschloss ich, Tests durchzuführen. Und zu meiner großen Enttäuschung konnte ich beim Kopieren keine Geschwindigkeitssteigerung von CoW feststellen. Hier ist das Ergebnis auf einer SATA-SSD:

time cp -a /usr /usr1 real 0m15,572s user 0m0,240s sys 0m4,739s 

Es stellte sich heraus, dass Sie zur Verwendung von CoW einen speziellen Schlüssel angeben müssen.

 time cp -a --reflink=auto /usr /usr2 real 0m3,166s user 0m0,178s sys 0m2,891s 

Nur in diesem Fall sehen wir einen 5-fachen Vorteil. Übrigens wächst die Größe des Vorteils mit zunehmender Dateilänge unbegrenzt. Der Ordner /usr , den ich kopiert habe, besteht hauptsächlich aus kleinen Dateien.

Ich war unglaublich überrascht, warum der Hauptvorteil des CoW-Dateisystems nicht standardmäßig verwendet wird. In der Tat wurde sie dafür geschaffen!

In diesem Fall habe ich das Kopieren im Abschnitt Btrfs getestet. Sie erhalten jedoch ein ähnliches Ergebnis mit jedem anderen CoW-Dateisystem, das Reflink unterstützt.

Was ist das Problem, Billy?


Das Problem ist in cp. Standardmäßig wird beim Kopieren keine CoW verwendet. Obwohl es kann.

Man kann sagen - ich benutze kein cp. Unter der Haube von Linux wird es jedoch fast überall verwendet. Viele Programme verwenden, wenn sie etwas kopieren müssen, cp und nicht ihre "Fahrräder".

Warum haben die Entwickler von coreutils eine so zweideutige Entscheidung getroffen, die die Hälfte der Vorteile von CoW-Dateisystemen durchgestrichen hat?

Es stellt sich heraus, dass Pádraig Brady, verantwortlich für die Entwicklung von GNU-Coreutils, dies entschieden hat.

Hier ist seine Logik :

  1. Standardmäßig verwendet cp keine CoW, da möglicherweise jemand das Kopieren verwendet, um die Wahrscheinlichkeit zu erhöhen, dass die Datei nach der Zerstörung des Dateisystems auf der Festplatte gespeichert wird.
  2. In Bezug auf die Leistung möchten Sie bei einem verzögerungsempfindlichen Prozess möglicherweise, dass der Hauptdatensatz während des Kopierens erstellt wird. Wenn dies später geschieht, kann es zu einer Verzögerung beim Neupositionieren der Köpfe der Festplatte kommen. Bitte beachten Sie, dass mv ab Version 8.24 coreutils standardmäßig die Option reflink verwendet.

Pádraig Brady antwortet auf Englisch
Dies ist nicht die Standardeinstellung, da aus Gründen der Robustheit möglicherweise eine Kopie zum Schutz vor Datenbeschädigung erstellt werden soll. Aus Leistungsgründen möchten Sie möglicherweise, dass die Schreibvorgänge zum Kopierzeitpunkt erfolgen und nicht zu einem latenzempfindlichen Prozess, der an einer CoW-Datei arbeitet und durch die Schreibvorgänge möglicherweise auf einen anderen Teil einer mechanischen Festplatte verzögert wird. Beachten Sie, dass mv von coreutils v8.24 standardmäßig neu flinkt, da es die oben genannten Einschränkungen nicht gibt.

In Bezug auf die Geschwindigkeit für MV gibt es praktisch keinen Vorteil von CoW beim Verschieben von Dateien. Innerhalb eines einzelnen Dateisystems arbeitet mv fast immer sehr schnell.

Wieder stellt sich die Frage nach dem Einfluss der Persönlichkeit auf die Geschichte. Indem Sie mehrere Buchstaben unterschiedlich in den Programmquellcode einfügen, können Sie das Kopieren für Dutzende / Hunderte Millionen Benutzer verlangsamen (hier müssen Sie berücksichtigen, dass die meisten Benutzer Cloud-Dienste in der einen oder anderen Form verwenden, auch wenn sie keinen Computer haben), wodurch die Effizienz der Verwendung von Laufwerken verringert wird und steigern ihren Umsatz weltweit.

Pádraig Argument Parsing


Das erste Argument macht Sinn. Unerfahrene Benutzer können tatsächlich wertvolle Dateien auf demselben Dateisystem sichern.

Zweites Argument. Wenn Sie weitere Kommentare zu den Verzögerungen von Pádraig lesen, werden Sie feststellen, dass er an Datenbanksituationen gedacht hat, in denen es beim Schreiben in eine vorhandene Datei zu Verzögerungen kommen kann, weil das Dateisystem nach freiem Speicherplatz sucht. Im Fall des CoW-Dateisystems werden jedoch aufgrund der Art der CoW immer nach neuen Sektoren für die Aufzeichnung gesucht, wie Jan Kanis feststellte. Daher ist das zweite Argument meiner Meinung nach unhaltbar.

Auf CoW-Systemen ist es jedoch tatsächlich möglich, beim Schreiben in die Datenbankdatei eine Verzögerung oder sogar den Fehler "Nicht genügend Speicherplatz" zu erhalten. Um dies zu vermeiden, müssen Sie zunächst ein leeres Verzeichnis mit deaktivierter CoW für die Datenbank erstellen.

Deaktivieren Sie CoW für das Verzeichnis / die Datei wie folgt:

 chattr +C /dir/file chattr +C /dir/dir 

Es besteht auch die Möglichkeit, Nodatacow zu montieren. Es wird auf alle neu erstellten Dateien angewendet.

Aber was ist, wenn wir beim Kopieren standardmäßig CoW verwenden möchten?


  1. Der radikale Weg besteht darin, Coreutils zu flicken. Möglicherweise erstellen Sie Ihr Paket in Ihrem privaten Repository.

    Patch cp.c Datei:

     -x->reflink_mode = REFLINK_NEVER; +x->reflink_mode = REFLINK_AUTO; 
  2. Eine weniger radikale Lösung besteht darin, einen CP-Alias ​​für Ihre Shell zu schreiben. Für Bash zum Beispiel:

    /etc/profile.d Ordner /etc/profile.d eine cp_reflink.sh cp_reflink.sh mit dem Inhalt:

     #!/bin/bash alias cp='cp --reflink=auto' 

    Diese Lösung funktioniert in fast allen Fällen, wenn auf cp über eine Shell mit Namen zugegriffen wird. Wenn jedoch / bin / cp in den Skripten verwendet wird, funktioniert der Alias ​​nicht und das Kopieren erfolgt wie gewohnt.

Dateimanager und Reflink


Stand 31. Oktober 2019:

  • Midnight Commander - unterstützt.
  • Krusader - unterstützt nicht.
  • Delphin - unterstützt nicht.
  • Nautilus - unterstützt nicht.
  • Nemo - Unterstützt.

Programmiersprachen, Systemaufrufe und Reflink


Die meisten Programmiersprachen unterstützen Reflinks nicht.
In C kopieren viele Programmierer immer noch mit Schleifen und Puffern .

Der sendfile -Systemaufruf verwendet kein Reflink.
cp verwendet den ioctl -Systemaufruf mit dem FICLONE-Flag.

Ich denke, wenn Sie etwas in den Code kopieren müssen, ist es ratsam, es wie cp zu tun oder einfach cp --reflink=auto .

Schlussfolgerungen


Mit dem Aufkommen der Ära der allgegenwärtigen Virtualisierung und SSD ist es sehr wichtig geworden, CoW-Dateisysteme zu verwenden. Sie eignen sich zum Erstellen von Schnappschüssen und zum schnellen Kopieren. Wenn Sie beim Kopieren CoW verwenden, führen wir automatisch eine Datendeduplizierung durch .

Derzeit unterstützen nur 3 Dateisysteme diesen Kopiertyp: BTRFS, XFS und OCFS2.

Ich hoffe aufrichtig, dass die Reflink-Unterstützung in ZFS und NILFS2 abgeschlossen wird, da sie CoW bereits durch interne Mechanismen unterstützen.

In allen Linux-Distributionen ist CoW jedoch beim Kopieren von Dateien deaktiviert, und wir müssen entweder die entsprechenden Schlüssel explizit angeben oder verschiedene Tricks wie Aliase oder Patches verwenden.

18 Jahre sind seit der Ankündigung von Reiser4 vergangen, aber bisher ist das leichte Kopieren von CoW nicht überall in unser Leben getreten.

PS Docker und CoW


Wissen Sie, dass Docker btrfs für seine Speicherung unterstützt? Diese Option muss aktiviert sein. Es ist standardmäßig nicht ausgewählt.

Das CoW-Dateisystem ist theoretisch die perfekte Ergänzung zur einfachen Virtualisierung, wenn verschiedene virtuelle Maschinen denselben Kernel verwenden.

Meiner Meinung nach ist es viel organischer als OverlayFS und Aufs, die technologische Krücken zur Simulation von CoW sind.

Um Btrfs in Docker verwenden zu können, benötigen Sie:

  1. Mounten Sie in einer Neuinstallation (ohne Images und virtuelle Maschinen) von Docker ein separates Btrfs-Volume in /var/lib/docker
  2. Hinzufügen von Optionen zur Docker-Startkonfigurationsdatei

Für Gentoo und Calculate Linux ist dies /etc/conf.d/docker

 DOCKER_OPTS="--storage-driver btrfs --data-root /var/lib/docker" 

Und hier ist die vollständige Anleitung für alle Distributionen.

Ergänzungen aus Kommentaren


XFS und CoW


constb ( Quelle ): Unter XFS wird CoW auch nicht immer unterstützt. Sie müssen ein Dateisystem mit mkfs.xfs -m reflink=1 erstellen.
Bereits auf dem erstellten FS können Sie die CoW-Unterstützung nicht aktivieren. Außerdem führt die Aufnahme dieser Option auf Kerneln bis 4.11 zu roten Warnungen in dmesg, dass die Funktion experimentell ist.

MacOS und CoW


MMik ( Quelle ): In OS X ist -c eine ähnliche Option wie der Befehl cp .

Dabei wird der atomare Systemaufruf clonefile() , der im Dateisystem einen Eintrag über eine neue Datei erstellt, in der die Verweise auf Datenblöcke mit dem Original identisch sind. Attribute und erweiterte Attribute der Datei werden kopiert, ACL-Einträge (Access Control List), mit Ausnahme der Informationen zum Dateieigentümer und mit dem Zurücksetzen der setuid / setgid-Bits. Es funktioniert im selben Dateisystem und muss vom Dateisystem unterstützt werden (Attribut ATTR_VOL_CAPABILITIES, Flag VOL_CAP_INT_CLONE).

Unterstützt seit OS X 10.12 (Sierra) und nur im APFS- Dateisystem.


Danksagung:


PPS Richten Sie die festgestellten Fehler in einem persönlichen. Ich erhöhe das Karma dafür.



Sie können mit CoW-Dateisystemen experimentieren, indem Sie eine virtuelle Maschine bei RUVDS mit dem folgenden Gutschein bestellen.

Source: https://habr.com/ru/post/de473752/


All Articles