Ich möchte ein Nginx-Cache-Verzeichnis löschen, das ich schnell gelöscht habe durch:
mv cache cache.bak
mkdir cache
service nginx restart
Jetzt habe ich einen cache.bak
Ordner mit 2 Millionen Dateien. Ich möchte es löschen, ohne den Server zu stören.
Ein einfacher rm -rf cache.bak
Papierkorb auf dem Server, selbst die einfachste HTTP-Antwort dauert 16 Sekunden, während rm ausgeführt wird, daher kann ich das nicht tun.
Ich habe es versucht ionice -c3 rm -rf cache.bak
, aber es hat nicht geholfen. Der Server verfügt über eine Festplatte, nicht über eine SSD. Wahrscheinlich ist dies auf einer SSD kein Problem.
Ich glaube, die beste Lösung wäre eine Art Drosselung, wie es der in Nginx integrierte Cache-Manager tut.
Wie würden Sie das lösen? Gibt es ein Tool, das genau das kann?
ext4 unter Ubuntu 16.04
linux
ubuntu
filesystems
ext4
Hyperknoten
quelle
quelle
rm
mit nice zu laufen ?Antworten:
Erstellen Sie ein Bash-Skript wie folgt:
Speichern Sie es
deleter.sh
zum Beispiel mit Namen . Führen Sie es auschmod u+x deleter.sh
, um es ausführbar zu machen.Dieses Skript löscht alle als Argumente übergebenen Dateien und schläft dann 0,5 Sekunden.
Dann kannst du rennen
Dieser Befehl ruft eine Liste aller Dateien in cache.bak ab und übergibt die fünf Dateinamen gleichzeitig an das Löschskript.
Sie können also einstellen, wie viele Dateien gleichzeitig gelöscht werden und wie lange zwischen den einzelnen Löschvorgängen eine Verzögerung liegt.
quelle
xargs
versteht die maximale Größe einer Befehlszeile und versucht, diese standardmäßig nicht zu überschreiten. Dieser hat zusätzliche Grenzen von nicht mehr als 5 Pfaden gleichzeitig.Sie sollten in Betracht ziehen, Ihren Cache in einem separaten Dateisystem zu speichern, das Sie wie in den Kommentaren angegeben ein- und aushängen können. Bis dahin können Sie diesen einen Liner verwenden,
/usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete
vorausgesetzt, Ihre Find-Binärdatei befindet sich unter / usr / bin und Sie möchten den Fortschritt auf dem Bildschirm sehen. Passen Sie den Schlaf entsprechend an, damit Ihre Festplatte nicht überlastet wird.quelle
-print0
hier nicht, da Sie die Ausgabe vonfind
nirgendwo leiten.Möglicherweise möchten Sie ionice in einem Skript ausprobieren, das die Ausgabe eines Suchbefehls verbraucht. So etwas wie das Folgende:
Abhängig vom Dateisystem kann jedes Löschen einer Datei dazu führen, dass das gesamte Verzeichnis neu geschrieben wird. Für große Verzeichnisse kann das ein ziemlicher Erfolg sein. Für die Inode-Tabelle sind möglicherweise zusätzliche Aktualisierungen und möglicherweise eine Liste mit freiem Speicherplatz erforderlich.
Wenn das Dateisystem über ein Journal verfügt, werden Änderungen in das Journal geschrieben. angewendet; und aus dem Tagebuch entfernt. Dies erhöht die E / A-Anforderungen für schreibintensive Aktivitäten.
Möglicherweise möchten Sie ein Dateisystem ohne Journal für den Cache verwenden.
Anstelle von ionice können Sie einen Schlafbefehl verwenden, um die Aktionen zu begrenzen. Dies funktioniert auch dann, wenn ionice dies nicht tut, aber es wird lange dauern, bis alle Ihre Dateien gelöscht sind.
quelle
Ich habe hier viele nützliche Antworten / Kommentare erhalten, die ich abschließen und auch meine Lösung zeigen möchte.
Ja, der beste Weg, dies zu verhindern , besteht darin, das Cache-Verzeichnis in einem separaten Dateisystem zu speichern. Das Nuking / schnelle Formatieren eines Dateisystems dauert immer höchstens einige Sekunden (möglicherweise Minuten), unabhängig davon, wie viele Dateien / Verzeichnisse darauf vorhanden waren.
Die
ionice
/nice
-Lösungen haben nichts getan, da der Löschvorgang tatsächlich fast keine E / A verursachte. Was die E / A verursacht hat, war meiner Meinung nach, dass sich Warteschlangen / Puffer auf Kernel- / Dateisystemebene füllen, wenn Dateien durch den Löschvorgang zu schnell gelöscht wurden.Die Art und Weise, wie ich es gelöst habe, ähnelt der Lösung von Tero Kilkanen, erfordert jedoch nicht das Aufrufen eines Shell-Skripts. Ich habe den eingebauten
--bwlimit
Schalter von rsync verwendet , um die Geschwindigkeit des Löschens zu begrenzen.Voller Befehl war:
Jetzt gibt bwlimit die Bandbreite in Kilobyes an, die in diesem Fall auf den Dateinamen oder den Pfad der Dateien angewendet wird. Durch Einstellen auf 1 KBit / s wurden ungefähr 100.000 Dateien pro Stunde oder 27 Dateien pro Sekunde gelöscht. Dateien hatten relative Pfade wie
cache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e
, was 47 Zeichen lang ist, also würde es 1000/47 ~ = 21 Dateien pro Sekunde geben, so ähnlich wie meine Schätzung von 100.000 Dateien pro Stunde.Warum jetzt
--bwlimit=1
? Ich habe verschiedene Werte ausprobiert:Ich mag die Einfachheit der eingebauten Methode von rsync, aber diese Lösung hängt von der relativen Pfadlänge ab. Kein großes Problem, da die meisten Menschen durch Ausprobieren den richtigen Wert finden würden.
quelle