Komprimieren vieler ähnlicher großer Dateien

3222
osgx

Ich habe Hunderte ähnlicher großer Dateien (jeweils 30 Megabyte), die ich komprimieren möchte. Jedes Paar von Dateien hat 99% der gleichen Daten (weniger als 1% Unterschied), daher erwarte ich nicht mehr als 40-50 Megabyte Archiv.

Einzelne Datei kann von 30 MB auf 13 bis 15 MB komprimiert wird (mit xz -1, gz -1, bzip2 -1), aber wenn zwei Komprimieren oder mehr Dateien mag ich Archiv haben, mit der Größe, 13-15MB + N*0.3MBwobei N Anzahl der Dateien ist.

Bei der Verwendung von tar(zum Erstellen eines soliden Archivs) und xz -6(um das Komprimierungswörterbuch als eine Datei zu definieren - Update - das war nicht genug! ), Habe ich immer noch ein Archiv mit Größe N*13MB.

Ich denke, dass beide gzipund bzip2wird mir helfen, nicht, weil sie Wörterbuch weniger als 1 MB haben, und mein Teerstrom hat Wiederholungen alle 30 MB.

Wie kann ich mein Problem in modernen Linux mit Standardwerkzeugen archivieren?

Kann man xzschnell komprimieren, aber ein größeres Wörterbuch als 30-60 MB verwenden?

Update : Habe den Trick mit gemacht tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. Nicht sicher über notwendige Optionen mf=hc4und --memory=2GOptionen; dict=128MLegen Sie jedoch fest, dass das Wörterbuch groß genug ist (größer als eine Datei), und mode=fastmachen Sie den Prozess etwas schneller als -e.

17
Das Ausführen von `xz -1 --memory = 2G` hat nicht geholfen, getestet mit 2 und 4 Dateien aus dem Set. osgx vor 10 Jahren 0

3 Antworten auf die Frage

12
woliveirajr

Ich gehe davon aus, dass Sie anhand Ihrer Angaben überprüft haben, dass Ihre Dateien tatsächlich 99% der Daten gemeinsam haben, wobei ein zusammenhängender (oder fast zusammenhängender) Unterschied von 1% besteht.

Zuerst sollten Sie tar verwenden, um ein Archiv mit Ihren Dateien darin zu erstellen. Für Tests würde ich eine .tar mit 10 Dateien erstellen, also 300 MB groß sein.

Wenn Sie dann xz verwenden, müssen Sie es so einstellen, dass das Wörterbuch größer ist als die Größe einer Datei. Da Sie nicht sagen, ob Sie Speicherbeschränkungen haben, würde ich mit xz -9 gehen. Es ist sinnlos, nicht den gesamten verfügbaren Speicher zu verwenden.

Ich würde auch das --extreme-Preset verwenden, um zu testen, ob es einen Unterschied macht.

Größe des Wörterbuchs

In einer Dokumentation, die mir zur Verfügung steht - site - heißt es, dass die Größe des Wörterbuchs in etwa der Speicherbelegung des Dekompressors entspricht. Der Parameter -1 bedeutet ein Diktier von 1MiB, -6 bedeutet 10 MiB (oder 8 MiB in einem anderen Teil des gleichen Handbuchs). Deshalb erhalten Sie keinen Vorteil, wenn Sie diese Dateien zusammenfassen. Mit -9 würde der Zerleger (und damit das Wörterbuch) 64 MiB betragen, und ich denke, das war es, was Sie wollten.

Bearbeiten

Eine andere Möglichkeit wäre die Verwendung eines anderen Kompressors. Ich würde mit 7zip gehen, würde aber diese Dateien zuerst tarieren und dann 7zip.

Je nach Inhalt Ihrer Dateien könnten Sie 7zip mit der PPM-D-Methode verwenden (anstelle von LZMA oder LZMA2 ist dies die Standardeinstellung und dieselbe, die von xz verwendet wird).

Nicht gut: Zip (dict = 32kB), Bzip (dict = 900 kB).

Xz und 7-Zip verwenden beide LZMA2, so dass dort kein Nutzen entsteht. PPMD ist für die extrem langsame Entropieextraktion mit hoher Komprimierungsrate aus bereits komprimierten Medien (z. B. MP3s und Video) optimiert. Es ist nicht besonders wahrscheinlich, dass die großen Ähnlichkeiten zwischen den beiden Dateien gefunden und im Wörterbuch gespeichert werden - nicht wahrscheinlicher als LZMA2. Horn OK Please vor 10 Jahren 0
woliveirajr, wie wäre es, wenn Sie nicht `-1` oder` -9` voreinstellen, sondern `dict = 64MB` oder` dict = 128MB` angeben und `mode = fast` setzen? osgx vor 10 Jahren 0
Die Verwendung von dict = xxMB anstelle von -1 oder -9 würde direkt zum Punkt führen, aber da ich nicht weiß, wie xz andere Parameter einstellt, wenn Sie nur -9 verwenden, weiß ich nicht, ob Sie etwas vermissen würden sonst. Ich denke, dass Sie in die richtige Richtung gehen, und nur das Testen gibt Ihnen eine genaue Antwort. woliveirajr vor 10 Jahren 0
Mit "xz --lzma2 = dict = 128M, Modus = schnell, mf = hc4 --memory = 2G" konnte ich 250 Dateien (7,5 GB) auf 18 MB tar.xz archivieren. osgx vor 10 Jahren 3
@osgx :) das ist ziemlich nett. Wenn es nicht zu lange gedauert hat (dh es liegt innerhalb Ihrer Bedürfnisse), ist das Problem gelöst! :) Sie haben also final_size = 13MB + x * 6kB, mehr oder weniger. woliveirajr vor 10 Jahren 0
9
Horn OK Please

Wenn sie wirklich zu 99% ähnlich sind, sollten Sie bsdiff oder einen ähnlichen Algorithmus verwenden können, um die Unterschiede zwischen den Dateien zu berechnen. Ist der Unterschied kumulativ (dh jede Datei unterscheidet sich ein wenig mehr von der ersten), oder ist der Unterschied zwischen zwei Dateien ziemlich gleich?

Wenn es nicht kumulativ ist, sollten Sie in der Lage sein:

  • Beliebige Dateien als "Baseline" verwenden
  • Führen Sie den bsdiffVergleich der Baseline-Datei mit jeder weiteren Datei aus
  • Speichern Sie jeden diff als separate Datei neben der Baseline-Datei
  • Führen Sie einen Kompressor wie bei xzden Ergebnissen aus (Basislinie + Diffs).

Das Ergebnis sollte viel kleiner sein als nur xzdas gesamte Archiv.

Sie können dann die Originaldateien "rekonstruieren", indem Sie den Diff oberhalb der Basislinie "anwenden", um alle anderen Dateien herauszuholen.

Nicht kumulativ ("Jedes Paar von Dateien enthält 99% der gleichen Daten ...") osgx vor 10 Jahren 0
Wenn die Unterschiede nicht kumulativ sind, sollte dies eine gute Anwendung des `bsdiff`-Algorithmus sein. Versuche es. Horn OK Please vor 10 Jahren 1
Vielen Dank für Ihre Antwort, aber ich habe die Aufgabe bereits mit xz erledigt: `tar c directory | xz --lzma2 = dict = 128M, mode = fast` und gelöschte Eingabedateien. Eigentlich waren meine Eingabedateien Text, so dass ich auch diff anstelle von "bsdiff" verwenden kann (was nicht auf meinem PC installiert ist). osgx vor 10 Jahren 0
4
osgx

Sie (I) können tar mit einem Archiver verwenden, der zur Erkennung von Mustern mit großer Reichweite geeignet ist, z. B. rzip oder lrzip ( Readme ). Beide verwenden eine Erkennung und Deduplizierung von Redundanzen mit großer Reichweite, dann verwendet rzip bzip2 und lrzip verwendet xz (lzma) / ZPAQ:

rzip ist ein Komprimierungsprogramm mit ähnlicher Funktionalität wie gzip oder bzip2, kann jedoch auch Fernredundanzen in Dateien nutzen, wodurch rzip manchmal bessere Komprimierungsraten als andere Programme erzielen kann. ... Der Hauptvorteil von rzip ist, dass es einen effektiven Historienpuffer von 900 MByte hat. Dies bedeutet, dass er im Vergleich zu anderen häufig verwendeten Komprimierungsprogrammen über große Entfernungen passende Teile der Eingabedatei finden kann. Das gzip-Programm verwendet im Vergleich dazu einen Verlaufspuffer von 32 KByte und bzip2 einen Verlaufspuffer von 900 KByte

lrzip hat einen größeren Puffer und kann nach der Deduplizierung viele Kompressionsalgorithmen verwenden (sehr schnell, schnell, gut und einer der besten - ZPAQ):

Lrzip verwendet eine erweiterte Version von rzip, die eine Redundanzreduktion für den ersten Durchlauf über große Entfernungen bewirkt. Die lrzip-Modifikationen lassen sie entsprechend der Speichergröße skalieren.

Die Daten sind dann entweder: 1. Komprimiert durch lzma (Standardeinstellung), was eine ausgezeichnete Komprimierung bei etwa der doppelten Geschwindigkeit der bzip2-Komprimierung ergibt

Ein anderer Weg ist die Verwendung von bup - Sicherungsprogramm mit Deduplizierung auf Block- / Segmentebene, basierend auf git packfile:

Es verwendet einen rollenden Prüfsummenalgorithmus (ähnlich wie bei rsync), um große Dateien in Blöcke aufzuteilen.