Comprimere molti file di grandi dimensioni simili


18

Ho centinaia di file simili simili (30 megabyte ciascuno) che voglio comprimere. Ogni coppia di file ha il 99% degli stessi dati (meno dell'1% di differenza), quindi mi aspetto di non avere più di 40-50 megabyte di archivio.

Singolo file può essere compresso da 30 MB a 13-15 MB (con xz -1, gz -1, bzip2 -1), ma quando comprimendo due o più file che voglio avere archivio con dimensioni 13-15MB + N*0.3MBdove N è il numero di file.

Quando uso tar(per creare un archivio solido) e xz -6(per definire un dizionario di compressione più grande di un file - Aggiornamento - questo non era abbastanza! ), Ho ancora un archivio con dimensioni N*13MB.

Penso che entrambi gzipe bzip2non mi aiuteranno perché hanno un dizionario inferiore a 1 MB e il mio flusso tar ha ripetizioni ogni 30 MB.

Come posso archiviare il mio problema in Linux moderno usando strumenti standard?

È possibile sintonizzarsi xzper comprimere velocemente, ma utilizzare un dizionario più grande di 30-60 MB?

Aggiornamento : ha fatto il trucco con tar c input_directory | xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2G > compressed.tar.xz. Non sono sicuro del necessario mf=hc4e delle --memory=2Gopzioni; ma dict=128Mimposta il dizionario in modo che sia sufficientemente grande (più grande di un file) e mode=fastrendi il processo un po 'più veloce di -e.


L'esecuzione xz -1 --memory=2Gnon ha aiutato, testato su 2 e 4 file dal set.
Osgx,

Risposte:


12

Dati i tuoi dettagli, presumo che tu abbia verificato che i tuoi file hanno davvero il 99% dei dati in comune, con un 1% di differenza contiguo (o quasi contiguo).

Innanzitutto, dovresti usare tar per creare un archivio con i tuoi file al suo interno. Per i test, creerei un .tar con 10 file, quindi con una dimensione di 300 MB.

Quindi, utilizzando xz, è necessario impostarlo in modo che il dizionario sia più grande della dimensione di un file. Dal momento che non dici se hai restrizioni di memoria, andrei con xz -9. Non ha senso non usare tutta la memoria disponibile.

Vorrei anche usare il preset --extreme, per verificare se fa differenza.

Dimensione del dizionario

In una documentazione che ho a disposizione - sito - si dice che la dimensione del dizionario è approssimativamente uguale all'uso della memoria del decompressore. E il parametro -1 indica un dict di 1 MiB, -6 significa 10 MiB (o 8 MiB in un'altra parte dello stesso manuale). Ecco perché non stai ottenendo alcun vantaggio mettendo insieme questi file. L'uso del -9 renderebbe il decompessore (e, quindi, il dizionario) di 64 MiB, e penso che sia quello che volevi.

modificare

Un'altra possibilità sarebbe quella di utilizzare un altro compressore. Andrei con 7zip, ma prima tarerei quei file e poi li 7zip.

A seconda del contenuto dei tuoi file, forse potresti usare 7zip con il metodo PPM-D (invece di LZMA o LZMA2, che è l'impostazione predefinita e la stessa usata da xz)

Non buono: Zip (dict = 32kB), Bzip (dict = 900 kB).


Xz e 7-Zip utilizzano entrambi LZMA2, quindi non ci sarebbe alcun vantaggio. PPMD è ottimizzato per l'estrazione dell'entropia di compressione estremamente lenta ma ad alta velocità da supporti già compressi (ad esempio MP3 e video). Non è particolarmente probabile trovare le grandi somiglianze tra i due file e memorizzarle nel dizionario - non più probabile di LZMA2.
allquixotic,

woliveirajr, che ne dici di usare not -1o -9preset, ma specificare dict=64MBo dict=128MBe impostare mode=fast?
Osgx,

L'uso di dict = xxMB invece di -1 o -9 andrebbe direttamente al punto, ma poiché non so come xz imposta altri parametri quando usi semplicemente -9, non so se non ti perderai qualcosa altro. Penso che tu sia nella giusta direzione, e solo i test ti daranno una risposta precisa.
woliveirajr

3
Con xz --lzma2=dict=128M,mode=fast,mf=hc4 --memory=2Gsono stato in grado di comprimere 250 file (7,5 GB) in 18 tar.xz archivio.
Osgx,

@osgx :) è carino. Se non ci è voluto troppo tempo (vale a dire, è nelle tue esigenze), problema risolto! :) Quindi hai final_size = 13MB + x * 6kB, più o meno.
woliveirajr,

9

Se sono davvero simili al 99% come dici tu, dovresti essere in grado di usare bsdiff o un algoritmo simile per calcolare le differenze tra i file. La differenza è cumulativa (ovvero, ogni file differisce un po 'di più dal primo) o la differenza tra due file è praticamente la stessa?

Se non è cumulativo, dovresti essere in grado di:

  • Prendi qualsiasi file arbitrario come "baseline"
  • Esegui bsdiffconfrontando il file di base con ciascun file aggiuntivo
  • Memorizza ogni differenziale come file separato, accanto al file di base
  • Esegui un compressore come xzattraverso i risultati (la linea di base + le differenze).

Il risultato dovrebbe essere molto più piccolo del semplice xzing dell'intero archivio.

È quindi possibile "ricostituire" i file originali "applicando" il diff sopra la linea di base per estrarre ciascuno degli altri file.


Non cumulativo ("Ogni coppia di file ha il 99% degli stessi dati ...")
osgx,

1
Se le differenze non sono cumulative, questa dovrebbe essere una buona applicazione bsdiffdell'algoritmo. Provaci.
allquixotic,

Grazie per la risposta, ma ho già svolto il compito con xz: tar c directory|xz --lzma2=dict=128M,mode=fasted eliminato i file di input. In realtà i miei file di input erano di testo, quindi posso anche usare diff invece di bsdiff(che non è installato sul mio PC).
Osgx,

5

L'utente (I) può utilizzare tar con alcuni archivi in ​​grado di rilevare pattern a lungo raggio, ad esempio rzip o lrzip ( Leggimi ). Entrambi utilizzano il rilevamento / deduplicazione a ridondanza a lungo raggio, quindi rzip utilizza bzip2 e lrzip utilizza xz (lzma) / ZPAQ:

rzip è un programma di compressione, simile nelle funzionalità a gzip o bzip2, ma in grado di sfruttare ridondanze a lunga distanza nei file, che a volte può consentire a rzip di produrre rapporti di compressione molto migliori rispetto ad altri programmi. ... Il principale vantaggio di rzip è che ha un buffer di cronologia efficace di 900 Mbyte. Ciò significa che può trovare parti corrispondenti del file di input a grandi distanze rispetto ad altri programmi di compressione comunemente usati. Il programma gzip al confronto utilizza un buffer di cronologia di 32 kbyte e bzip2 utilizza un buffer di cronologia di 900 kbyte

lrzip ha un buffer più grande e può usare molti algoritmi di compressione (molto veloce, veloce, buono e uno dei migliori - ZPAQ) dopo la deduplicazione:

Lrzip utilizza una versione estesa di rzip che riduce il ridondanza a lunga distanza di primo passaggio. Le modifiche di lrzip lo fanno ridimensionare in base alle dimensioni della memoria.

I dati sono quindi: 1. Compresso da lzma (impostazione predefinita) che offre una compressione eccellente a circa il doppio della velocità della compressione bzip2 ...

L'altro modo è usare il programma di backup bup con deduplicazione a livello di blocco / segmento, basato su git packfile:

Utilizza un algoritmo di checksum continuo (simile a rsync) per dividere i file di grandi dimensioni in blocchi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.