Zeit, um sehr große (100G) Dateien zu komprimieren

27

Ich muss einige sehr große Dateien komprimieren (80-ish GB), und ich bin überrascht über die (fehlende) Geschwindigkeit, die mein System aufweist. Ich erhalte eine Konvertierungsgeschwindigkeit von ca. 500 MB / min. Unter Verwendung von topscheint ich eine einzelne CPU mit ungefähr 100% zu verwenden.

Ich bin mir ziemlich sicher, dass es nicht (nur) die Geschwindigkeit des Festplattenzugriffs ist, da das Erstellen einer tarDatei (so wurde die 80G-Datei erstellt) nur wenige Minuten (vielleicht 5 oder 10) gedauert hat, aber nach mehr als 2 Stunden ist mein einfacher gzip-Befehl immer noch nicht durchgeführt.

Zusammenfassend:

tar -cvf myStuff.tar myDir/*

Es dauerte <5 Minuten, um eine 87-G-Teer-Datei zu erstellen

gzip myStuff.tar

Es dauerte zwei Stunden und 10 Minuten, um eine 55G-Zip-Datei zu erstellen.

Meine Frage: Ist das normal? Gibt es bestimmte Möglichkeiten gzip, die Dinge zu beschleunigen? Wäre es schneller, die Befehle zu verketten und zu verwenden tar -cvfz? Ich sah Bezug auf pigz- parallele Implementierung von GZIP - aber leider kann ich keine Software auf dem Rechner installieren Ich verwende, so dass für mich keine Option ist. Siehe zum Beispiel diese frühere Frage .

Ich beabsichtige, einige dieser Optionen selbst auszuprobieren und zu testen - aber es ist sehr wahrscheinlich, dass ich nicht die "magische Kombination" von Optionen treffen werde. Ich hoffe, dass jemand auf dieser Seite den richtigen Trick kennt, um die Dinge zu beschleunigen.

Wenn ich die Ergebnisse anderer Versuche zur Verfügung habe, werde ich diese Frage aktualisieren - aber wenn jemand einen besonders guten Trick zur Verfügung hat, würde ich es wirklich begrüßen. Vielleicht braucht der gzip einfach mehr Verarbeitungszeit, als mir klar wurde ...

AKTUALISIEREN

Wie versprochen habe ich die folgenden Tricks ausprobiert: Ändern Sie den Komprimierungsgrad und das Ziel der Datei. Ich habe die folgenden Ergebnisse für einen Teer erhalten, der ungefähr 4,1 GB groß war:

flag    user      system   size    sameDisk
-1     189.77s    13.64s  2.786G     +7.2s 
-2     197.20s    12.88s  2.776G     +3.4s
-3     207.03s    10.49s  2.739G     +1.2s
-4     223.28s    13.73s  2.735G     +0.9s
-5     237.79s     9.28s  2.704G     -0.4s
-6     271.69s    14.56s  2.700G     +1.4s
-7     307.70s    10.97s  2.699G     +0.9s
-8     528.66s    10.51s  2.698G     -6.3s
-9     722.61s    12.24s  2.698G     -4.0s

Wenn ich also das Flag vom Standard -6zum schnellsten -1ändere, habe ich eine 30% ige Beschleunigung, wobei sich (für meine Daten) kaum etwas an der Größe der ZIP-Datei ändert. Ob ich dieselbe oder eine andere Festplatte verwende, spielt im Wesentlichen keine Rolle (ich müsste dies mehrere Male ausführen, um statistische Signifikanz zu erhalten).

Bei Interesse habe ich diese Timing-Benchmarks mit den folgenden beiden Skripten generiert:

#!/bin/bash
# compare compression speeds with different options
sameDisk='./'
otherDisk='/tmp/'
sourceDir='/dirToCompress'
logFile='./timerOutput'
rm $logFile

for i in {1..9}
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $sameDisk $logFile
  do  /usr/bin/time -a --output=timerOutput ./compressWith $sourceDir $i $otherDisk $logFile
done

Und das zweite Skript ( compressWith):

#!/bin/bash
# use: compressWith sourceDir compressionFlag destinationDisk logFile
echo "compressing $1 to $3 with setting $2" >> $4
tar -c $1 | gzip -$2 > $3test-$2.tar.gz

Drei Dinge zu beachten:

  1. Verwenden /usr/bin/timestatt time, da der eingebaute Befehl von bashviel weniger Optionen hat als der GNU-Befehl
  2. Ich habe mich nicht darum gekümmert, die --formatOption zu verwenden, obwohl dies die Lesbarkeit der Protokolldatei verbessern würde
  3. Ich habe ein Skript-in-einem-Skript verwendet, da timees nur beim ersten Befehl in einer Pipe-Sequenz zu funktionieren schien (also habe ich es wie einen einzelnen Befehl aussehen lassen ...).

Nach all diesen Erkenntnissen sind meine Schlussfolgerungen

  1. Beschleunigen Sie die Dinge mit der -1Flagge (akzeptierte Antwort)
  2. Das Komprimieren der Daten kostet viel mehr Zeit als das Lesen von der Festplatte
  3. Investieren Sie in eine schnellere Komprimierungssoftware ( pigzscheint eine gute Wahl zu sein).
  4. Wenn Sie mehrere Dateien zum Komprimieren haben, können Sie jeden gzipBefehl in einen eigenen Thread stellen und mehr von der verfügbaren CPU (dem armen Mann pigz) verwenden.

Vielen Dank an alle, die mir geholfen haben, das alles zu lernen!

Floris
quelle
tar -cvf macht keine Komprimierung, daher wird es schneller
parkydr
2
@ Floris: Welche Art von Daten versuchen Sie zu komprimieren? Nebenbemerkung: $> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gzZeigt an, wie schnell Ihre Maschine das Material komprimiert. Randnotiz2: Speichern Sie das Ergebnis auf einer anderen Disc.
Akira
3
Entschuldigung, ich habe Ihre Frage falsch verstanden. gzip hat die Option --fast, um die schnellste Komprimierung auszuwählen
parkydr
1
@parkydr: Die --fast-Option ist eine, von der ich nichts wusste ... es ist die allerletzte auf der manSeite, und ich habe sie nicht so weit gelesen (weil sie nach "Einzelbuchstaben-Befehl" sortiert ist -#). . Das bringt mir RTFM bei! Dies wird das nächste sein, was ich versuche!
Floris
2
Wenn auf dem Computer ein geeigneter Compiler verfügbar ist und die Dateisystemberechtigungen nicht so eingestellt sind, dass die Ausführung von Binärdateien aus den Verzeichnissen, auf die Sie zugreifen können, untersagt ist, können Sie pigzihn von jedem Ort aus kompilieren und ausführen, an dem Sie ihn erstellt haben, ohne ihn zu installieren. Wenn es keinen Compiler gibt, können Sie ihn auf einem anderen Computer übergreifend kompilieren, obwohl dies mehr Aufwand verursacht, als es möglicherweise wert ist. (Je nachdem, wie dringend Sie diese Komprimierung benötigen, um schneller zu laufen, denke ich.)
David Z

Antworten:

27

Sie können die Geschwindigkeit von gzip mit --fast --bestoder ändern, -#wobei # eine Zahl zwischen 1 und 9 ist (1 ist am schnellsten, aber weniger komprimiert, 9 ist am langsamsten, aber mehr komprimiert). Standardmäßig wird gzip auf Stufe 6 ausgeführt.

Robingrindrod
quelle
26

Der Grund, warum tar im Vergleich zu gzip so wenig Zeit in Anspruch nimmt, besteht darin, dass das Kopieren Ihrer Dateien in eine einzelne Datei nur einen geringen Rechenaufwand verursacht (was auch immer der Fall ist). gzip verwendet dagegen Komprimierungsalgorithmen, um die TAR-Datei zu verkleinern.

Das Problem ist, dass gzip (wie Sie festgestellt haben) auf einen einzelnen Thread beschränkt ist.

Geben Sie pigz ein , das mehrere Threads verwenden kann, um die Komprimierung durchzuführen. Ein Beispiel dafür wäre:

tar -c --use-compress-program=pigz -f tar.file dir_to_zip

Es gibt eine nette kurze Zusammenfassung der Option --use-compress-program auf einer Schwestersite .

Steve Gore
quelle
Vielen Dank für Ihre Antwort und Links. Ich habe Pigz tatsächlich in der Frage erwähnt.
Floris
Dies ist die richtige Antwort hier ..!
Stolsvik
4

Ich scheine eine einzelne CPU bei ungefähr 100% zu verwenden.

Dies impliziert, dass es kein Problem mit der E / A-Leistung gibt, sondern dass für die Komprimierung nur ein Thread verwendet wird (was bei gzip der Fall ist).

Wenn Sie den für die Installation anderer Tools erforderlichen Zugriff / die erforderliche Vereinbarung erreichen, unterstützt 7zip auch mehrere Threads, um die Vorteile von Multi-Core-CPUs zu nutzen. Ich bin mir jedoch nicht sicher, ob dies auch für das gzip-Format gilt.

Wenn Sie momentan nur gzip verwenden und mehrere Dateien komprimieren möchten, können Sie versuchen, sie einzeln zu komprimieren. Auf diese Weise können Sie mehr von dieser Multi-Core-CPU verwenden, indem Sie mehr als einen Prozess parallel ausführen. Achten Sie jedoch darauf, es nicht zu übertreiben, da die Leistung Ihres E / A-Subsystems, sobald Sie sich der Kapazität annähern, schnell abnimmt (zu niedrig, als wenn Sie einen Prozess / Thread verwenden), da die Latenz der Kopfbewegungen erheblich wird Engpass.

David Spillett
quelle
danke für deinen Beitrag. Sie haben mir eine Idee gegeben (für die Sie eine Gegenstimme erhalten): Da ich mehrere Archive erstellen muss, kann ich einfach die einzelnen Befehle gefolgt von einem schreiben &und das System von dort aus erledigen lassen. Jeder wird auf einem eigenen Prozessor ausgeführt, und da ich viel mehr Zeit für die Komprimierung als für die E / A-Verarbeitung aufbringe, dauert es genauso lange, einen zu erstellen, wie für alle zehn. So bekomme ich "Multi-Core-Leistung" von einer ausführbaren Datei, die Single-Threaded ist ...
Floris
1

Man kann die Anzahl der verfügbaren Prozesse auch in pigz ausnutzen, was normalerweise eine schnellere Leistung ist, wie im folgenden Befehl gezeigt

tar cf - Verzeichnis zum Archivieren | pigz -0 -p größe> mydir.tar.gz

Beispiel - tar cf - patha | pigz -0 -p 32> patha.tar.gz

Dies ist wahrscheinlich schneller als die im Beitrag vorgeschlagenen Methoden, da -p die Anzahl der Prozesse angibt, die ausgeführt werden können. Nach meiner persönlichen Erfahrung beeinträchtigt das Festlegen eines sehr großen Werts die Leistung nicht, wenn das zu archivierende Verzeichnis aus einer großen Anzahl kleiner Dateien besteht. Anderenfalls wird ein Standardwert von 8 berücksichtigt. Für große Dateien würde ich empfehlen, diesen Wert als Gesamtzahl der auf dem System unterstützten Threads festzulegen.

Beispiel: Das Setzen eines Wertes von p = 32 bei einer 32-CPU-Maschine hilft.

0 ist für die schnellste Pigz-Komprimierung gedacht, da es das Archiv nicht komprimiert und sich eher auf die Geschwindigkeit konzentriert. Der Standardwert für die Komprimierung ist 6.

Ankit Shah
quelle