È ora di comprimere file di dimensioni molto grandi (100 G)


27

Mi ritrovo a dover comprimere un numero di file molto grandi (80-ish GB) e sono sorpreso dalla (mancanza di) velocità che il mio sistema sta esibendo. Ottengo una velocità di conversione di circa 500 MB / min; usando top, mi sembra di usare una singola CPU a circa il 100%.

Sono abbastanza sicuro che non sia (solo) la velocità di accesso al disco, poiché la creazione di un tarfile (è così che è stato creato il file 80G) ha richiesto solo pochi minuti (forse 5 o 10), ma dopo più di 2 ore il mio semplice comando gzip è ancora non fatto.

In sintesi:

tar -cvf myStuff.tar myDir/*

Sono stati necessari <5 minuti per creare un file tar da 87 G

gzip myStuff.tar

Ci sono voluti due ore e 10 minuti, creando un file zip 55G.

La mia domanda: è normale? Ci sono alcune opzioni gzipper accelerare le cose? Sarebbe più veloce concatenare i comandi e utilizzarli tar -cvfz? Ho visto riferimento a pigz- Implementazione parallela di GZip - ma sfortunatamente non riesco a installare il software sulla macchina che sto usando, quindi non è un'opzione per me. Vedi ad esempio questa domanda precedente .

Ho intenzione di provare alcune di queste opzioni da solo e cronometrarle - ma è molto probabile che non colpirò "la combinazione magica" di opzioni. Spero che qualcuno su questo sito conosca il trucco giusto per accelerare le cose.

Quando avrò i risultati di altre prove disponibili, aggiornerò questa domanda, ma se qualcuno ha un trucco particolarmente utile disponibile, lo apprezzerei molto. Forse il gzip richiede solo più tempo di elaborazione di quanto pensassi ...

AGGIORNARE

Come promesso, ho provato i trucchi suggeriti di seguito: modificare la quantità di compressione e cambiare la destinazione del file. Ho ottenuto i seguenti risultati per un tar che era di circa 4,1 GB:

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

Quindi sì, cambiando il flag dal default -6al più veloce -1mi dà uno speedup del 30%, con (per i miei dati) quasi nessuna modifica alle dimensioni del file zip. Che io stia usando lo stesso disco o un altro non fa praticamente alcuna differenza (dovrei eseguirlo più volte per ottenere un significato statistico).

Se qualcuno è interessato, ho generato questi benchmark di temporizzazione usando i seguenti due script:

#!/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

E il secondo script ( 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

Tre cose da notare:

  1. Usando /usr/bin/timepiuttosto che time, dato che il comando integrato di bashha molte meno opzioni rispetto al comando GNU
  2. Non mi sono preoccupato di usare l' --formatopzione, anche se ciò renderebbe più facile la lettura del file di registro
  3. Ho usato uno script-in-a-script poiché timesembrava funzionare solo sul primo comando in una sequenza convogliata (quindi l'ho fatto sembrare un singolo comando ...).

Con tutto ciò appreso, le mie conclusioni sono

  1. Accelera le cose con la -1bandiera (risposta accettata)
  2. Passa molto più tempo a comprimere i dati che a leggere dal disco
  3. Investi in un software di compressione più veloce ( pigzsembra una buona scelta).
  4. Se hai più file da comprimere puoi mettere ogni gzipcomando nel suo thread e usare più della CPU disponibile (povero pigz)

Grazie a tutti coloro che mi hanno aiutato a imparare tutto questo!


tar -cvf non esegue alcuna compressione, quindi sarà più veloce
parkydr,

2
@Floris: che tipo di dati stai cercando di comprimere? nota a margine: $> gzip -c myStuff.tar | pv -r -b > myStuff.tar.gzti mostrerà quanto velocemente la tua macchina sta comprimendo le cose. side-note2: memorizza il risultato su un altro disco.
Akira,

3
Mi dispiace, ho letto male la tua domanda. gzip ha l'opzione --fast per selezionare la compressione più veloce
parkydr

1
@parkydr: L'opzione --fast è una di cui non sapevo ... è l'ultima nella manpagina e non ho letto così lontano (perché è ordinata per 'comando a lettera singola', che è -#) . Questo mi insegnerà a RTFM! Questa sarà la prossima cosa che proverò!
Floris,

2
Si noti che se sulla macchina è disponibile un compilatore adatto e le autorizzazioni del file system non sono impostate per vietare l'esecuzione di file binari dalle directory a cui si ha accesso, è possibile compilarlo pigzed eseguirlo da qualsiasi luogo in cui sia stato creato, senza installarlo. Se non esiste un compilatore, è possibile compilarlo in modo incrociato su un altro computer, anche se questo sta iniziando a fare più sforzo di quanto potrebbe valerne la pena. (A seconda di quanto sia necessaria questa compressione per funzionare più velocemente, immagino.)
David Z,

Risposte:


27

Puoi cambiare la velocità di gzip usando --fast --besto -#dove # è un numero compreso tra 1 e 9 (1 è il più veloce ma meno compressione, 9 è il più lento ma più compressione). Per impostazione predefinita, gzip viene eseguito al livello 6.


26

Il motivo per cui tar richiede così poco tempo rispetto a gzip è che c'è un sovraccarico computazionale nel copiare i tuoi file in un singolo file (che è quello che fa). gzip d'altra parte, in realtà sta usando algoritmi di compressione per ridurre il file tar.

Il problema è che gzip è vincolato (come hai scoperto) a un singolo thread.

Inserisci pigz , che può utilizzare più thread per eseguire la compressione. Un esempio di come utilizzare questo sarebbe:

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

C'è un bel riepilogo succint dell'opzione --use-compress-program su un sito affiliato .


Grazie per la risposta e i collegamenti. In realtà ho menzionato pigz nella domanda.
Floris,

Questa è la risposta corretta qui ..!
stolsvik,

4

Mi sembra di usare una singola CPU a circa il 100%.

Ciò implica che non esiste un problema di prestazioni I / O ma che la compressione utilizza solo un thread (come nel caso di gzip).

Se riesci a ottenere l'accesso / l'accordo necessario per installare altri strumenti, 7zip supporta anche più thread per sfruttare le CPU multi core, anche se non sono sicuro che ciò si estenda al formato gzip e al suo.

Se per il momento sei bloccato ad usare solo gzip e hai più file da comprimere, potresti provare a comprimerli singolarmente, in questo modo utilizzerai più di quella CPU multi-core eseguendo più di un processo in parallelo. Fai attenzione a non esagerare perché, non appena ti avvicini alla capacità del sottosistema I / O, le prestazioni diminuiranno precipitosamente (a un livello inferiore rispetto a se stessi utilizzando un processo / thread) poiché la latenza dei movimenti della testa diventa significativa collo di bottiglia.


grazie per il tuo contributo. Mi hai dato un'idea (per la quale ottieni un voto): poiché ho più archivi da creare, posso solo scrivere i singoli comandi seguiti da un &- quindi lasciare che il sistema se ne occupi da lì. Ognuno verrà eseguito sul proprio processore e dal momento che dedico molto più tempo alla compressione che all'I / O, ci vorrà lo stesso tempo per fare uno che per fare tutti e 10. Quindi ottengo "prestazioni multi core" da un eseguibile a thread singolo ...
Floris,

1

Si può sfruttare anche il numero di processi disponibili in pigz, che di solito è prestazioni più veloci, come mostrato nel seguente comando

tar cf - directory da archiviare | pigz -0 -p grande> mydir.tar.gz

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

Questo è probabilmente più veloce dei metodi suggeriti nel post poiché -p è il numero di processi che è possibile eseguire. Nella mia esperienza personale, l'impostazione di un valore molto elevato non influisce negativamente sulle prestazioni se la directory da archiviare è composta da un numero elevato di file di piccole dimensioni. In caso contrario, il valore predefinito considerato è 8. Per file di grandi dimensioni, la mia raccomandazione sarebbe quella di impostare questo valore come numero totale di thread supportati sul sistema.

Esempio di impostazione di un valore di p = 32 nel caso di una macchina a 32 CPU aiuta.

0 è pensato per la compressione pigz più veloce in quanto non comprime l'archivio e si concentra piuttosto sulla velocità. Il valore predefinito è 6 per la 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.