Löschen Sie effektiv 10M + -Dateien aus ZFS

30

Ich habe ein fehlerhaftes Programm geschrieben, das versehentlich ungefähr 30 Millionen Dateien unter / tmp erstellt hat. (Der Bug wurde vor einigen Wochen eingeführt und erzeugte ein paar Unterverzeichnisse pro Sekunde.) Ich konnte / tmp in / tmp2 umbenennen und jetzt muss ich die Dateien löschen. Das System ist FreeBSD 10, das Root-Dateisystem ist zfs.

In der Zwischenzeit ist eine der Festplatten im Spiegel defekt, und ich habe sie ausgetauscht. Das Laufwerk verfügt über zwei 120 GB SSD-Festplatten.

Hier ist die Frage: Der Austausch der Festplatte und die Neusilberung des gesamten Arrays dauerten weniger als eine Stunde. Dateien löschen / tmp2 ist eine andere Geschichte. Ich habe ein anderes Programm geschrieben, um die Dateien zu entfernen, und es kann nur 30-70 Unterverzeichnisse pro Sekunde löschen. Das Löschen aller Dateien dauert 2-4 Tage.

Wie ist es möglich, dass das Resilbern des gesamten Arrays eine Stunde dauert, das Löschen von der Festplatte jedoch 4 Tage dauert? Warum habe ich so schlechte Leistung? 70 Löschungen / Sekunde scheinen eine sehr sehr schlechte Leistung zu sein.

Ich könnte den Inode für / tmp2 manuell löschen, aber das wird den Speicherplatz nicht freigeben, oder?

Könnte dies ein Problem mit zfs sein, oder den Festplatten oder was?

Nagylzs
quelle
1
Ich bin kein ZFS-Experte, daher kann ich nicht mit Ihrer Leistungsoptimierung sprechen oder was Sie tun könnten, um sie zu verbessern. Ich kann jedoch sagen, dass Resilvering auf Blockebene stattfindet, während Ihre Löschvorgänge auf Dateisystemebene stattfinden. Das Dateisystem wird größtenteils überlastet sein, wenn ein Bagillion Inode-Puffer wie dieser gelöscht wird.
Spooler
Bitte posten Sie Ihre df -hund zpool listund zfs list.
Ewwhite
5
Geschrieben ein anderes Programm: rm -rf /tmp2wird den Job nicht machen?
Thorbjørn Ravn Andersen
2
Könnten Sie nicht einfach neu starten? /tmpsollte ein tmpfsDateisystem sein und wird im Speicher abgelegt.
Blender

Antworten:

31

Löschvorgänge in ZFS sind teuer. Dies gilt umso mehr, wenn Sie die Deduplizierung für das Dateisystem aktiviert haben (da die Dereferenzierung deduplizierter Dateien teuer ist). Schnappschüsse könnten die Sache ebenfalls komplizieren.

Möglicherweise ist es besser, das /tmpVerzeichnis zu löschen, als die darin enthaltenen Daten.

Wenn /tmpes sich um ein ZFS-Dateisystem handelt, löschen Sie es und erstellen es erneut.

ewwhite
quelle
1
@nagylzs In diesem Fall würde ich vorschlagen, ein separates ZFS-Dateisystem zu erstellen. Dann können Sie das aktuelle / tmp aus dem Weg räumen, ein neues / tmp an die richtige Stelle verschieben und die Dateien nach Belieben des Systems löschen. Ergebnis: Minimale Ausfallzeit plus eine leichte Leistungsverschlechterung (abzufedern ionice, sofern FreeBSD dies zulässt ), während der Löschvorgang ausgeführt wird.
ein Lebenslauf
9
Ich lag falsch. Es war ein separates Dateisystem. Folgendes hat funktioniert: Starten Sie in den Einzelbenutzermodus und führen Sie dann "zfs delete zroot / tmp; zfs create zroot / tmp; chmod 41777 / tmp"
nagylzs
6
Es waren insgesamt 5 Minuten Ausfallzeit. Fantastisch! :-)
Nagylzs
1
Nun, das spricht auch für die Besorgnis, dass das Löschen von Fikes aufgrund von Schnappschüssen niemals Speicherplatz freigibt. Aber tmp wird so eingestellt, dass keine automatischen periodischen Schnappschüsse erstellt werden, oder ?
JDługosz
1
Eigentlich war das: zfs create -o compression = on -o exec = on -o setuid = off zroot / tmp; chmod 1777 / zroot / tmp; zfs set mountpoint = / tmp zroot / tmp; Ich bin mir jedoch nicht sicher, wie ich automatische Schnappschüsse deaktivieren soll. Es gibt "zfs set com.sun: auto-snapshot = false", aber das funktioniert meiner Meinung nach nur unter Solaris.
Nagylzs
27

Wie ist es möglich, dass das Resilbern des gesamten Arrays eine Stunde dauert, das Löschen von der Festplatte jedoch 4 Tage dauert?

Betrachten Sie ein Bürogebäude.

Das Entfernen aller Computer, Möbel und Befestigungen aus allen Büros auf allen Etagen dauert sehr lange , verlässt jedoch die Büros, die von einem anderen Kunden sofort genutzt werden können.

Der Abriss des gesamten Gebäudes mit RDX geht viel schneller, aber der nächste Kunde wird sich mit ziemlicher Wahrscheinlichkeit darüber beschweren, wie zugig der Platz ist.

Phill W.
quelle
5
ZFS ist kein Bürogebäude :)
Developerbmw
9
@developerbmw Es gibt dort auch keine Datei oder einen Ordner, aber wir brauchen metaphorische Konzepte, um zu verstehen, was los ist.
James Ryan
2
@ James Ryan yep es ist eigentlich eine schöne Analogie ... Ich war nur dumm
Developerbmw
5

Hier ist eine Reihe von Dingen im Gange.

Erstens sind alle modernen Festplattentechnologien für Massentransfers optimiert. Wenn Sie 100 MB Daten verschieben müssen, geschieht dies viel schneller, wenn sie sich in einem zusammenhängenden Block befinden, anstatt über den gesamten Bereich verteilt zu sein. SSDs helfen hier sehr, aber selbst sie bevorzugen Daten in zusammenhängenden Blöcken.

Zweitens ist Resilvering in Bezug auf Festplattenvorgänge ziemlich optimal. Sie lesen einen großen zusammenhängenden Datenblock von einer Festplatte, führen einige schnelle CPU-Operationen durch und schreiben ihn dann in einem weiteren großen zusammenhängenden Block auf eine andere Festplatte. Wenn die Stromversorgung nach einer Weile ausfällt, ist das keine große Sache - Sie ignorieren einfach alle Daten mit schlechten Prüfsummen und fahren wie gewohnt fort.

Drittens ist das Löschen einer Datei sehr langsam . ZFS ist besonders schlecht, aber praktisch alle Dateisysteme lassen sich nur langsam löschen. Sie müssen eine große Anzahl von verschiedenen Datenblöcken auf der Festplatte ändern und korrekt zeitlich festlegen (dh warten), damit das Dateisystem bei einem Stromausfall nicht beschädigt wird.

Wie ist es möglich, dass das Resilbern des gesamten Arrays eine Stunde dauert, das Löschen von der Festplatte jedoch 4 Tage dauert?

Resilvering ist etwas, bei dem Festplatten sehr schnell sind, und das Löschen ist etwas, bei dem Festplatten langsam sind. Pro Megabyte Festplatte müssen Sie nur ein wenig nachsilbern. Möglicherweise befinden sich in diesem Bereich tausend Dateien, die gelöscht werden müssen.

70 Löschungen / Sekunde scheinen eine sehr sehr schlechte Leistung zu sein

Es hängt davon ab, ob. Das würde mich nicht überraschen. Sie haben nicht erwähnt, welchen SSD-Typ Sie verwenden. Moderne Intel- und Samsung-SSDs sind in dieser Art von Operation (Lesen, Ändern, Schreiben) ziemlich gut und weisen eine bessere Leistung auf. Billigere / ältere SSDs (zB Corsair) werden langsam sein. Die Anzahl der E / A-Operationen pro Sekunde (IOPS) ist hier der bestimmende Faktor.

ZFS ist besonders langsam Dinge zu löschen. Normalerweise werden Löschvorgänge im Hintergrund ausgeführt, sodass die Verzögerung nicht angezeigt wird. Wenn Sie eine große Anzahl von ihnen tun, kann es nicht verbergen und muss Sie verzögern.


Anhang: Warum sind Löschvorgänge langsam?

  • Das Löschen einer Datei erfordert mehrere Schritte. Die Dateimetadaten müssen als "gelöscht" markiert und schließlich zurückgefordert werden, damit der Speicherplatz wiederverwendet werden kann. ZFS ist ein Dateisystem mit Protokollstruktur, das am besten funktioniert, wenn Sie nur Objekte erstellen und niemals löschen. Die Protokollstruktur bedeutet, dass beim Löschen eine Lücke im Protokoll vorhanden ist und daher andere Daten neu angeordnet (defragmentiert) werden müssen, um die Lücke zu füllen. Dies ist für den Benutzer unsichtbar, aber im Allgemeinen langsam.
  • Die Änderungen müssen so vorgenommen werden, dass bei einem Stromausfall das Dateisystem konsistent bleibt. Dies bedeutet häufig, dass Sie warten müssen, bis die Festplatte bestätigt, dass sich die Daten tatsächlich auf dem Datenträger befinden. Bei einer SSD kann dies sehr lange dauern (Hunderte von Millisekunden). Der Nettoeffekt davon ist, dass es viel mehr Buchhaltung gibt (dh Platten-E / A-Operationen).
  • Alle Änderungen sind klein. Anstatt ganze Flash-Blöcke (oder Zylinder für eine Magnetplatte) zu lesen, zu schreiben und zu löschen, müssen Sie ein wenig von einem ändern. Dazu muss die Hardware einen ganzen Block oder Zylinder einlesen, im Speicher ändern und dann erneut auf das Medium schreiben. Das dauert lange.
Ian Howson
quelle
Ich weiß nichts über ZFS, aber einige Dateisysteme ermöglichen es Ihnen, die Verknüpfung eines Verzeichnisses mit Inhalten aufzuheben, aber diese Inhalte werden erst später während einer Garbage Collection / Defrag / Cleanup-Phase entfernt. Hat ZFS irgendwelche Hilfsprogramme, um eine solche verzögerte Löschung durchzuführen? Es wird das Löschen des OP nicht wirklich beschleunigen, würde es aber wahrscheinlich weniger problematisch machen, wenn es implizit während des Reinigungsvorgangs geschieht.
Vality
2

Wie ist es möglich, dass das Resilbern des gesamten Arrays eine Stunde dauert, das Löschen von der Festplatte jedoch 4 Tage dauert?

Dies ist möglich, da die beiden Vorgänge auf verschiedenen Ebenen des Dateisystemstapels ausgeführt werden. Resilvering kann auf niedriger Ebene ausgeführt werden und muss nicht unbedingt einzelne Dateien anzeigen, um große Datenmengen gleichzeitig zu kopieren.

Warum habe ich so schlechte Leistung? 70 Löschungen / Sekunde scheinen eine sehr sehr schlechte Leistung zu sein.

Es muss eine Menge Buchhaltung tun ...

Ich könnte den Inode für / tmp2 manuell löschen, aber das wird den Speicherplatz nicht freigeben, oder?

Ich weiß es nicht für ZFS, aber wenn es sich automatisch davon erholen könnte, würde es wahrscheinlich am Ende die gleichen Vorgänge ausführen, die Sie bereits im Hintergrund ausführen.

Könnte dies ein Problem mit zfs sein, oder den Festplatten oder was?

Sagt zfs scrubnichts

AnoE
quelle
2

Das Löschen vieler Dateien ist nie wirklich ein schneller Vorgang.

Um eine Datei in einem Dateisystem zu löschen , müssen Sie den Dateiindex lesen, den Dateieintrag im Index entfernen (oder als gelöscht markieren), alle anderen der Datei zugeordneten Metadaten entfernen und den für die Datei zugewiesenen Speicherplatz als markieren ungebraucht. Dies muss für jede zu löschende Datei einzeln durchgeführt werden, was bedeutet, dass zum Löschen vieler Dateien viele kleine E / As erforderlich sind. Dies auf eine Weise zu tun, die die Datenintegrität im Falle eines Stromausfalls gewährleistet, erhöht den Overhead noch mehr.

Selbst ohne die von ZFS eingeführten Besonderheiten bedeutet das Löschen von 30 Millionen Dateien in der Regel mehr als hundert Millionen separate E / A-Vorgänge. Dies dauert auch bei einer schnellen SSD sehr lange. Wie bereits erwähnt, wird dieses Problem durch das Design von ZFS noch verstärkt.

bwDraco
quelle
2

Ian Howson gibt eine gute Antwort darauf, warum es langsam ist.

Wenn Sie Dateien parallel löschen, kann es vorkommen, dass sich die Geschwindigkeit aufgrund des Löschvorgangs erhöht. Dies kann dazu führen, dass dieselben Blöcke verwendet werden und das erneute Schreiben desselben Blocks möglicherweise um ein Vielfaches gespart wird.

Also versuche:

find /tmp -print0 | parallel -j100 -0 -n100 rm

und sehen Sie, ob dies eine bessere Leistung als Ihre 70 Löschvorgänge pro Sekunde erbringt.

Ole Tange
quelle
0

Sehr einfach, wenn Sie Ihr Denken umkehren.

  1. Holen Sie sich eine zweite Fahrt (Sie scheinen dies bereits zu haben)

  2. Kopieren Sie mit rsync alles von Laufwerk A auf Laufwerk B, mit Ausnahme des Verzeichnisses / tmp. Rsync ist langsamer als eine Blockkopie.

  3. Starten Sie neu und verwenden Sie Laufwerk B als neues Startvolume

  4. Formatieren Sie Laufwerk A neu.

Dadurch wird auch Ihr Laufwerk defragmentiert und Sie erhalten ein neues Verzeichnis (in Ordnung, Defragmentierung ist bei einer SSD nicht so wichtig, aber die Linearisierung Ihrer Dateien schadet nichts).

Peter
quelle
Kopieren Sie zunächst alles außer / tmp? Also inklusive / dev und / proc? Zweitens klingt es für mich etwas klobig, besonders auf einem Produktionsserver.
Hennes
Ich gehe davon aus, dass er klug genug ist, um Nicht-Dateien, gemountete Volumes und den Ordner für den virtuellen Speicher auszuschließen, von denen die meisten hier nicht erraten werden können. Oder machen Sie es von einem Wartungsboot aus, wo keines dieser Dinge von Bedeutung ist.
Peter
Ich denke, Sie könnten auch zfs send/recvalle anderen Dateisysteme außer dem Root-Dateisystem (in diesem Fall befindet sich / tmp) kopieren (Block-Level-Kopie) und die restlichen Daten manuell auf das Root-Dateisystem kopieren (natürlich ohne / tmp).
user121391
2
Dadurch gehen die Schnappschüsse verloren und einige der Zuverlässigkeitsfunktionen werden umgangen. Verpasst den Punkt der Verwendung von ZFS.
JDługosz
2
@ JDługosz gültige Punkte, aber nur relevant, wenn der Benutzer interessiert. So ähnlich wie "Meine Backups sind beschädigt, wie kann ich sie reparieren?" -> "Benötigen Sie Sicherungsdateien?" -> "Nein." -> "Neu formatieren".
Peter
-1

Sie haben 30 Millionen Einträge in einer unsortierten Liste. Sie durchsuchen die Liste nach dem Eintrag, den Sie entfernen möchten, und entfernen ihn. Jetzt haben Sie nur 29.999.999 Einträge in Ihrer unsortierten Liste. Wenn sie alle in / tmp sind, warum nicht einfach neu starten?


Bearbeitet, um die Informationen in den Kommentaren widerzuspiegeln: Problembeschreibung: Das Entfernen der meisten, aber nicht aller fehlerhaft erstellten 30M + -Dateien in / tmp dauert sehr lange.
Problem 1) Der beste Weg, um eine große Anzahl unerwünschter Dateien aus / tmp zu entfernen.
Problem 2) Verstehen, warum das Löschen von Dateien so langsam ist.

Lösung 1) - / tmp wird von den meisten * nix-Distributionen beim Booten auf leer zurückgesetzt. FreeBSD gehört jedoch nicht dazu.
Schritt 1 - Kopieren Sie interessante Dateien an eine andere Stelle.
Schritt 2 - Als root

 $ grep -i tmp /etc/rc.conf  
 clear_tmp_enable="YES" # Clear /tmp at startup.  

Schritt 3 - Neustart.
Schritt 4 - clear_tmp_enable wieder auf "Nein" setzen.
Unerwünschte Dateien gehen verloren, da ZFS unter FreeBSD die Funktion hat, dass "das Löschen eines Datasets viel schneller geht als das Löschen aller Dateien, die sich auf dem Dataset befinden, da nicht alle Dateien gescannt und alle entsprechenden Metadaten aktualisiert werden müssen. " Alles, was Sie beim Booten tun müssen, ist, die Metadaten für das / tmp-Dataset zurückzusetzen. Das geht sehr schnell.

Lösung 2) Warum ist es so langsam? ZFS ist ein wunderbares Dateisystem, das Funktionen wie den ständigen Zugriff auf Verzeichnisse enthält. Dies funktioniert gut, wenn Sie wissen, was Sie tun, aber die Beweise deuten darauf hin, dass das OP kein ZFS-Experte ist. Das OP hat nicht angegeben, wie sie versucht haben, die Dateien zu entfernen, aber vermutlich haben sie eine Variation von "find regex -exec rm {} \;" verwendet. Dies funktioniert gut mit kleinen Zahlen, ist jedoch nicht skalierbar, da drei serielle Operationen ablaufen: 1) Liste der verfügbaren Dateien abrufen (30 Millionen Dateien in Hash-Reihenfolge zurückgeben), 2) Regex verwenden, um die nächste zu löschende Datei auszuwählen, 3 ) das Betriebssystem anweisen, diese Datei aus einer Liste von 30 Millionen zu finden und zu entfernen. Auch wenn ZFS eine Liste aus dem Speicher zurückgibt und wenn 'find' speichert es zwischen, der Regex muss die nächste zu verarbeitende Datei aus der Liste identifizieren und dann das Betriebssystem anweisen, seine Metadaten zu aktualisieren, um diese Änderung widerzuspiegeln, und die Liste dann zu aktualisieren, damit sie nicht erneut verarbeitet wird.

Paul Smith
quelle
1
Ich denke, Sie haben die Frage falsch verstanden. Ich musste die meisten Dateien entfernen. Das sind über 30 Millionen Dateien.
Nagylzs
@nagylzs / tmp wird beim Neustart gelöscht. Wenn Sie die meisten Dateien löschen möchten, möchten Sie nur einige , dh weniger als die Hälfte, behalten. Kopieren Sie die gewünschten Dateien, und starten Sie den Computer neu, um den Rest zu entfernen. Der Grund, warum Ihre Löschvorgänge so langsam sind, besteht darin, dass eine große Anzahl von Dateien in einem Verzeichnis zu einer großen unsortierten Liste führt, die verarbeitet werden muss, um die zu bearbeitende Datei zu finden, was einige Zeit in Anspruch nimmt. Das einzige Problem hier ist PEBCAK.
Paul Smith
ZFS-Verzeichnisse sind unsortiert ? Ich dachte, dass zfs speziell große Verzeichnisse gut handhabt.
JDługosz
Nun, / tmp wird nicht gelöscht, nur X-bezogene Dateien. Zumindest auf FreeBSD. Es kann ohnehin nicht beim Booten gelöscht werden, da es Tage dauern würde, bis das rc-Skript normal gelöscht wird.
Nagylzs
@JDlugosz - ZFS ist viel besser als die meisten anderen, aber Inode-Listen (das sind alle Verzeichnisse) sind unsortiert.
Paul Smith