Komprimieren vieler ähnlich großer Dateien

18

Ich habe Hunderte von ähnlich großen Dateien (jeweils 30 Megabyte), die ich komprimieren möchte. Jedes Dateipaar enthält 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.

Wenn ich tar(um ein solides Archiv zu erstellen) und xz -6(um das Komprimierungswörterbuch so zu definieren, dass es größer als eine Datei ist - Aktualisieren - das war nicht genug! ) Verwende , habe ich immer noch ein Archiv mit Größe N*13MB.

Ich denke, dass beide gzipund bzip2mir nicht helfen werden, da sie weniger als 1 MB Wörterbuch haben und mein Teer-Stream alle 30 MB Wiederholungen hat.

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

Ist es möglich, xzdie Komprimierung schnell einzustellen, aber ein Wörterbuch zu verwenden, das größer als 30-60 MB ist?

Update : Hab den Trick mit gemacht tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. Nicht sicher notwendig , von mf=hc4und --memory=2GOptionen; aber dict=128Mdas Wörterbuch gesetzt groß genug (größer als eine Datei) zu sein, und mode=fastmachen den Prozess etwas schneller als -e.

osgx
quelle
Laufen xz -1 --memory=2Ghat nicht geholfen, getestet an 2 und 4 Dateien aus dem Set.
osgx

Antworten:

12

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

Zuerst sollten Sie tar verwenden, um ein Archiv mit Ihren Dateien darin zu erstellen. Für Tests würde ich eine .tar-Datei mit 10 Dateien und einer Größe von 300 MB erstellen.

Dann müssen Sie mit xz festlegen, dass das Wörterbuch größer als die Größe einer Datei ist. Da Sie nicht sagen, ob Sie Speicherbeschränkungen haben, würde ich mit xz -9 gehen. Es hat keinen Sinn, nicht den gesamten verfügbaren Speicher zu nutzen.

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

Wörterbuchgröße

In einer verfügbaren Dokumentation - Site - heißt es, dass die Größe des Wörterbuchs in etwa der Speicherauslastung des Dekomprimierers entspricht. Und der Parameter -1 bedeutet ein Diktat von 1 MB, -6 bedeutet 10 MB (oder 8 MB in einem anderen Teil desselben Handbuchs). Das ist der Grund, warum Sie keinen Vorteil erzielen, wenn Sie diese Dateien zusammenfassen. Die Verwendung von -9 würde den Dekompensator (und damit das Wörterbuch) auf 64 MiB bringen, und ich denke, das ist, was Sie wollten.

Bearbeiten

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

Abhängig vom Inhalt Ihrer Dateien könnten Sie 7zip mit der PPM-D-Methode verwenden (anstelle von LZMA oder LZMA2, das ist die Standardeinstellung und die gleiche, die von xz verwendet wird).

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

woliveirajr
quelle
Xz und 7-Zip verwenden beide LZMA2, sodass es dort keinen Nutzen gibt. PPMD ist für die Entropieextraktion mit extrem langsamer, aber hoher Komprimierungsrate von bereits komprimierten Medien (z. B. MP3s und Videos) 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.
Allquixotic
woliveirajr, was ist mit nicht -1oder -9voreingestellt, sondern angeben dict=64MBoder dict=128MBund setzen mode=fast?
osgx
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 verpassen würden sonst. Ich denke, dass Sie in die richtige Richtung gehen und nur das Testen gibt Ihnen eine präzise Antwort.
Woliveirajr
3
Mit konnte xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2Gich 250 Dateien (7,5 GB) auf 18 MB tar.xz-Archiv komprimieren.
osgx
@osgx :) das ist ziemlich nett. Wenn es nicht zu lange gedauert hat (dh es liegt innerhalb Ihrer Bedürfnisse), ist das Problem gelöst! :) Du hast also final_size = 13MB + x * 6kB, mehr oder weniger.
Woliveirajr
9

Wenn sie wirklich zu 99% ähnlich sind, sollten Sie in der Lage sein, bsdiff oder einen ähnlichen Algorithmus zu verwenden, 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:

  • Nehmen Sie eine beliebige Datei als "Basis"
  • Führen Sie bsdiffdie Baseline - Datei jede zusätzliche Datei zu vergleichen
  • Speichern Sie jedes Diff als separate Datei neben der Basisdatei
  • Führen Sie einen Kompressor wie xzüber die Ergebnisse (die Basislinie + die Unterschiede).

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

Sie können dann die ursprünglichen Dateien "rekonstruieren", indem Sie das Diff oben auf der Grundlinie "anwenden", um alle anderen Dateien zu erhalten.

allquixotic
quelle
Nicht kumulativ. ("Jedes
Dateipaar enthält
1
Wenn die Unterschiede nicht kumulativ sind, sollte dies eine gute Anwendung des bsdiffAlgorithmus sein. Versuche es.
Allquixotic
Vielen Dank für Ihre Antwort, aber ich habe die Aufgabe bereits mit xz: erledigt tar c directory|xz --lzma2=dict=128M,mode=fastund Eingabedateien gelöscht. Eigentlich waren meine Eingabedateien Text, daher kann ich stattdessen auch diff verwenden bsdiff(was auf meinem PC nicht installiert ist).
osgx
5

Sie (I) können tar mit einigen Archiven verwenden, die zur Erkennung von Mustern mit großer Reichweite fähig sind, z. B. rzip oder lrzip ( Readme ). Beide verwenden die Erkennung / Deduplizierung von Redundanzen über große Entfernungen, dann verwendet rzip bzip2 und lrzip xz (lzma) / ZPAQ:

rzip ist ein Komprimierungsprogramm, das in seiner Funktionalität gzip oder bzip2 ähnelt, jedoch in der Lage ist, Fernreduktionen in Dateien zu nutzen, wodurch rzip manchmal viel bessere Komprimierungsverhältnisse als andere Programme erzeugt. ... Der Hauptvorteil von rzip ist, dass es einen effektiven Verlaufspuffer von 900 MB hat. Dies bedeutet, dass es im Vergleich zu anderen häufig verwendeten Komprimierungsprogrammen über große Entfernungen passende Teile der Eingabedatei finden kann. Das gzip-Programm verwendet im Vergleich einen Verlaufspuffer von 32 KByte und bzip2 einen Verlaufspuffer von 900 KByte

lrzip hat einen größeren Puffer und verwendet nach der Deduplizierung möglicherweise viele Komprimierungsalgorithmen (sehr schnell, schnell, gut und einer der besten - ZPAQ):

Lrzip verwendet eine erweiterte Version von rzip, mit der die Redundanzredundanz bei langen Entfernungen im ersten Durchgang reduziert wird. Durch die lrzip-Modifikationen wird die Größe des Speichers angepasst.

Die Daten sind dann entweder: 1. Komprimiert mit lzma (Standard), was eine hervorragende Komprimierung mit ungefähr der doppelten Geschwindigkeit der bzip2-Komprimierung ergibt ...

Eine andere Möglichkeit ist die Verwendung von bup - backup mit Deduplizierung auf Block- / Segmentebene, basierend auf git packfile:

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

osgx
quelle