Utilizzo di multi core per compressione / decompressione tar + gzip / bzip


225

Normalmente comprimere usando tar zcvfe decomprimere usando tar zxvf(usando gzip per abitudine).

Recentemente ho ottenuto una CPU quad core con hyperthreading, quindi ho 8 core logici e noto che molti dei core non vengono utilizzati durante la compressione / decompressione.

Esiste un modo per utilizzare i core non utilizzati per renderlo più veloce?


La soluzione proposta da Xiong Chiamiov sopra funziona magnificamente. Avevo appena eseguito il backup del mio laptop con .tar.bz2 e ci sono voluti 132 minuti usando solo un thread CPU. Quindi ho compilato e installato tar dal sorgente: gnu.org/software/tar Ho incluso le opzioni menzionate nel passaggio di configurazione: ./configure --with-gzip = pigz --with-bzip2 = lbzip2 --with-lzip = plzip Ho eseguito di nuovo il backup e ci sono voluti solo 32 minuti. È meglio del miglioramento 4X! Ho guardato il monitor di sistema e ha mantenuto tutti i 4 cpus (8 thread) in linea piatta al 100% per tutto il tempo. QUELLA è la soluzione migliore.
Warren Severin il

Risposte:


309

Puoi usare pigz invece di gzip, che esegue la compressione gzip su più core. Invece di usare l'opzione -z, la instraderesti attraverso pigz:

tar cf - paths-to-archive | pigz > archive.tar.gz

Per impostazione predefinita, pigz utilizza il numero di core disponibili, o otto se non è stato possibile interrogarlo. Puoi chiedere di più con -pn, ad esempio -p 32. pigz ha le stesse opzioni di gzip, quindi puoi richiedere una migliore compressione con -9. Per esempio

tar cf - paths-to-archive | pigz -9 -p 32 > archive.tar.gz

3
Come usi pigz per decomprimere allo stesso modo? O funziona solo per la compressione?
user788171

42
pigz utilizza più core per la decompressione, ma solo con un miglioramento limitato rispetto a un singolo core. Il formato di deflazione non si presta alla decompressione parallela. La parte di decompressione deve essere eseguita in serie. Gli altri core per la decompressione dei pigz sono usati per leggere, scrivere e calcolare il CRC. Quando si comprime invece, pigz si avvicina a un fattore di n miglioramento con n core.
Mark Adler,

7
Il trattino qui è stdout (vedi questa pagina ).
Garrett

3
Sì. 100% compatibile in entrambe le direzioni.
Mark Adler,

4
In effetti non c'è tempo di CPU speso a combattere, quindi non sarebbe di grande aiuto. Il formato tar è solo una copia del file di input con blocchi di intestazione tra i file.
Mark Adler,

324

Puoi anche usare il flag tar "--use-compress-program =" per dire a tar quale programma di compressione usare.

Ad esempio usare:

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

21
Questa è una piccola pepita di conoscenza e merita più voti. Non avevo idea che esistesse questa opzione e ho letto la pagina man alcune volte nel corso degli anni.
Randall Hunt,

2
@ValerioSchiavoni: Non qui, ottengo pieno carico su tutti e 4 i core (Ubuntu 15.04 'Vivid').
bovender

8
Preferisco che il tar - dir_to_zip | pv | pigz > tar.filepv mi aiuti a stimare, puoi saltarlo. Ma è ancora più facile scrivere e ricordare.
Offenso,

@ NathanS.Watson-Haigh Sì, sì. Devi solo racchiudere il nome del programma e gli argomenti tra virgolette. man tardice così, come fa questo .
Marc.2377,

1
Nel 2020 zstdè lo strumento più veloce per farlo. Accelerazione notevole durante la compressione e la decompressione. Utilizzare tar -cf --use-compress-program=zstdmtper farlo con il multi-threading.
jadelord,

112

Approccio comune

C'è un'opzione per il tarprogramma:

-I, --use-compress-program PROG
      filter through PROG (must accept -d)

È possibile utilizzare la versione multithread dell'utilità di archiviazione o compressore.

Gli archiviatori multithread più popolari sono pigz (anziché gzip) e pbzip2 (anziché bzip2). Per esempio:

$ tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 paths_to_archive
$ tar --use-compress-program=pigz -cf OUTPUT_FILE.tar.gz paths_to_archive

Archiver deve accettare -d. Se l'utilità di sostituzione non ha questo parametro e / o è necessario specificare parametri aggiuntivi, utilizzare i tubi (aggiungere parametri se necessario):

$ tar cf - paths_to_archive | pbzip2 > OUTPUT_FILE.tar.gz
$ tar cf - paths_to_archive | pigz > OUTPUT_FILE.tar.gz

L'ingresso e l'uscita di singlethread e multithread sono compatibili. È possibile comprimere utilizzando la versione multithread e decomprimere utilizzando la versione singlethread e viceversa.

p7zip

Per p7zip per la compressione è necessario uno script di shell piccolo come il seguente:

#!/bin/sh
case $1 in
  -d) 7za -txz -si -so e;;
   *) 7za -txz -si -so a .;;
esac 2>/dev/null

Salvalo come 7zhelper.sh. Ecco l'esempio di utilizzo:

$ tar -I 7zhelper.sh -cf OUTPUT_FILE.tar.7z paths_to_archive
$ tar -I 7zhelper.sh -xf OUTPUT_FILE.tar.7z

xz

Per quanto riguarda il supporto XZ multithread. Se si esegue la versione 5.2.0 o successiva di XZ Utils, è possibile utilizzare più core per la compressione impostando -To --threadssu un valore appropriato tramite la variabile ambientale XZ_DEFAULTS (ad es XZ_DEFAULTS="-T 0".).

Questo è un frammento di man per la versione 5.1.0alpha:

La compressione e decompressione multithread non sono ancora implementate, quindi questa opzione non ha alcun effetto per ora.

Tuttavia, ciò non funzionerà per la decompressione di file che non sono stati compressi anche con il threading abilitato. Da man per la versione 5.2.2:

La decompressione filettata non è stata ancora implementata. Funzionerà solo su file che contengono più blocchi con informazioni sulle dimensioni nelle intestazioni dei blocchi. Tutti i file compressi in modalità multi-thread soddisfano questa condizione, ma i file compressi in modalità single-thread non lo fanno nemmeno se si utilizza --block-size = size.

Ricompilazione con sostituzione

Se si crea tar da fonti, è possibile ricompilare con i parametri

--with-gzip=pigz
--with-bzip2=lbzip2
--with-lzip=plzip

Dopo aver ricompilato tar con queste opzioni è possibile controllare l'output della guida di tar:

$ tar --help | grep "lbzip2\|plzip\|pigz"
  -j, --bzip2                filter the archive through lbzip2
      --lzip                 filter the archive through plzip
  -z, --gzip, --gunzip, --ungzip   filter the archive through pigz

1
Questa è davvero la risposta migliore. Ricostruirò sicuramente il mio catrame!

1
Ho appena trovato pbzip2 e mpibzip2 . mpibzip2 sembra molto promettente per i cluster o, ad esempio, se hai un laptop e un computer desktop multicore.

Questa è una risposta grande ed elaborata. Può essere utile menzionare che la compressione multithread (ad es. Con pigz) è abilitata solo quando legge dal file. L'elaborazione di STDIN potrebbe infatti essere più lenta.
oᴉɹǝɥɔ

3
Più 1 per xzopzione. È l'approccio più semplice ma efficace.
selurvedu,

2
export XZ_DEFAULTS="-T 0"prima di chiamare tarcon l'opzione -Jper la compressione xz funziona come un incantesimo.
scai,

13

Puoi usare la scorciatoia -Iper tar's --use-compress-programswitch e invocare la pbzip2compressione bzip2 su più core:

tar -I pbzip2 -cf OUTPUT_FILE.tar.bz2 DIRECTORY_TO_COMPRESS/

Un bel TL; DR per la risposta di @ MaximSuslov .
einpoklum,

Questo restituisce tar: home/cc/ziptest: Cannot stat: No such file or directory tar: Exiting with failure status due to previous errors`
Arash il

1

Se vuoi avere maggiore flessibilità con i nomi di file e le opzioni di compressione, puoi usare:

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec \
tar -P --transform='s@/my/path/@@g' -cf - {} + | \
pigz -9 -p 4 > myarchive.tar.gz

Passo 1: find

find /my/path/ -type f -name "*.sql" -o -name "*.log" -exec

Questo comando cercherà i file che si desidera archiviare, in questo caso /my/path/*.sqle /my/path/*.log. Aggiungi quanti -o -name "pattern"ne vuoi.

-execeseguirà il comando successivo usando i risultati di find:tar

Passo 2: tar

tar -P --transform='s@/my/path/@@g' -cf - {} +

--transformè un semplice parametro di sostituzione della stringa. Spoglia il percorso dei file dall'archivio in modo che la radice del tarball diventi la directory corrente durante l'estrazione. Nota che non puoi usare l' -Copzione per cambiare directory poiché perderai i vantaggi di find: tutti i file della directory verrebbero inclusi.

-Pdice tardi usare percorsi assoluti, quindi non attiva l'avvertimento "Rimozione di` / 'iniziali dai nomi dei membri ". Il comando "/" iniziale verrà rimosso --transformcomunque.

-cf -dice tardi usare il nome tarball che specificheremo più avanti

{} +usa tutti i file findtrovati in precedenza

Passaggio 3: pigz

pigz -9 -p 4

Usa tutti i parametri che vuoi. In questo caso -9è il livello di compressione ed -p 4è il numero di core dedicati alla compressione. Se lo esegui su un server Web pesante, probabilmente non vorrai utilizzare tutti i core disponibili.

Passaggio 4: nome dell'archivio

> myarchive.tar.gz

Finalmente.


0

Uno strumento di compressione (de) relativamente più recente che potresti prendere in considerazione è zstandard . Fa un ottimo lavoro nell'utilizzare core di riserva e ha fatto alcuni grandi compromessi quando si tratta del rapporto di compressione rispetto al (de) tempo di compressione. È anche altamente ottimizzabile a seconda delle esigenze del rapporto di compressione.

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.