Comprimi velocemente un gran numero di file di grandi dimensioni


16

Ho circa 200 GB di dati di registro generati ogni giorno, distribuiti tra circa 150 diversi file di registro.

Ho uno script che sposta i file in una posizione temporanea e fa un tar-bz2 nella directory temporanea.

Ottengo buoni risultati poiché i registri da 200 GB vengono compressi a circa 12-15 GB.

Il problema è che ci vuole un'eternità per comprimere i file. Il cron job viene eseguito ogni giorno alle 2:30 e continua fino alle 17: 00-18: 00 PM.

C'è un modo per migliorare la velocità della compressione e completare il lavoro più velocemente? Qualche idea?

Non preoccuparti di altri processi e tutto il resto, la posizione in cui avviene la compressione è su un NAS , e posso eseguire il mount del NAS su una VM dedicata ed eseguire lo script di compressione da lì.

Ecco l'output di top per riferimento:

top - 15:53:50 up 1093 days,  6:36,  1 user,  load average: 1.00, 1.05, 1.07
Tasks: 101 total,   3 running,  98 sleeping,   0 stopped,   0 zombie
Cpu(s): 25.1%us,  0.7%sy,  0.0%ni, 74.1%id,  0.0%wa,  0.0%hi,  0.1%si,  0.1%st
Mem:   8388608k total,  8334844k used,    53764k free,     9800k buffers
Swap: 12550136k total,      488k used, 12549648k free,  4936168k cached
 PID  USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 7086 appmon    18   0 13256 7880  440 R 96.7  0.1 791:16.83 bzip2
7085  appmon    18   0 19452 1148  856 S  0.0  0.0   1:45.41 tar cjvf /nwk_storelogs/compressed_logs/compressed_logs_2016_30_04.tar.bz2 /nwk_storelogs/temp/ASPEN-GC-32459:nkp-aspn-1014.log /nwk_stor
30756 appmon    15   0 85952 1944 1000 S  0.0  0.0   0:00.00 sshd: appmon@pts/0
30757 appmon    15   0 64884 1816 1032 S  0.0  0.0   0:00.01 -tcsh

2
Se disponi di più CPU e le hai o puoi dividerle in più file tar, puoi eseguire più compressioni.
Jeff Schaller

@JeffSchaller sarebbe possibile ottenere più processi bzip2 comprimere file diversi ma scrivere nello stesso tar.bz2file?
anu,

2
I file di registro vengono generati sul disco locale prima di passare al NAS? In tal caso comprimere quindi spostare; in questo modo invii solo 15 GB di dati in rete anziché 100 (sposta) e poi 115 (100 lettura + 15 scrittura) durante la compressione. In alternativa sembra che tu possa essere associato alla CPU in quel processo bzip2, quindi l'esecuzione di più in parallelo (uno per CPU) potrebbe aiutare (fino a quando non raggiungi il limite I / O). Oppure utilizza una compressione più semplice (ad esempio "gzip -1"). Non risparmierà tanto spazio su disco ma funzionerà più velocemente.
Stephen Harris,

@Sukminder Lo proverò sicuramente e vedrò la differenza di dimensioni. Grazie.
anu,

L' topoutput mostra che il bzip2processo a thread singolo sta esaurendo al massimo un core, ma che lo stai eseguendo su un sistema quad-core (un processo che utilizza CPU al 100% -> 25.1%tempo CPU spazio utente, 74% inattivo). Quindi, con piccole modifiche, puoi andare 4 volte più veloce, a meno che qualcos'altro diventi il ​​collo di bottiglia. Leggi la risposta di Gilles con attenzione. Prendi in considerazione l'utilizzo della CPU nella stessa casella dei dischi che contengono i dati per eseguire la compressione. (Potresti persino comprimere alcuni dei tuoi file su una scatola, altri sull'altra e archiviarli dopo, quindi vengono utilizzate entrambe le CPU.)
Peter Cordes,

Risposte:


25

Il primo passo è capire qual è il collo di bottiglia: si tratta di I / O su disco, I / O di rete o CPU?

Se il collo di bottiglia è l'I / O del disco, non c'è molto che puoi fare. Assicurarsi che i dischi non soddisfino molte richieste parallele in quanto ciò può solo ridurre le prestazioni.

Se il collo di bottiglia è l'I / O di rete, eseguire il processo di compressione sulla macchina in cui sono archiviati i file: eseguirlo su una macchina con una CPU più robusta aiuta solo se la CPU è il collo di bottiglia.

Se il collo di bottiglia è la CPU, la prima cosa da considerare è l'utilizzo di un algoritmo di compressione più veloce. Bzip2 non è necessariamente una cattiva scelta - la sua principale debolezza è la velocità di decompressione - ma potresti usare gzip e sacrificare alcune dimensioni per la velocità di compressione, oppure provare altri formati come lzop o lzma. Puoi anche regolare il livello di compressione: bzip2 è impostato di default -9(dimensione massima del blocco, quindi massima compressione, ma anche tempo di compressione più lungo); imposta la variabile d'ambiente BZIP2su un valore come -3provare il livello di compressione 3. Questo thread e questo thread discutono algoritmi di compressione comuni; in particolare questo post di blog citato da derobert fornisce alcuni parametri di riferimento che suggeriscono che o con un livello basso potrebbe essere un buon compromesso rispetto a . Questo altro punto di riferimentogzip -9bzip2bzip2 -9 che include anche lzma (l'algoritmo di 7zip, quindi si potrebbe usare al 7zposto di tar --lzma) suggerisce che lzmaa un livello basso può raggiungere più velocemente il rapporto di compressione bzip2. Quasi ogni scelta diversa da bzip2 migliorerà il tempo di decompressione. Tieni presente che il rapporto di compressione dipende dai dati e la velocità di compressione dipende dalla versione del programma di compressione, da come è stato compilato e dalla CPU su cui viene eseguito.

Un'altra opzione se il collo di bottiglia è la CPU e si hanno più core è di parallelizzare la compressione. Ci sono due modi per farlo. Uno che funziona con qualsiasi algoritmo di compressione è comprimere i file separatamente (singolarmente o in alcuni gruppi) e utilizzare parallelper eseguire i comandi di archiviazione / compressione in parallelo. Ciò può ridurre il rapporto di compressione ma aumenta la velocità di recupero di un singolo file e funziona con qualsiasi strumento. L'altro approccio consiste nell'utilizzare un'implementazione parallela dello strumento di compressione; questa discussione ne elenca diverse.


4
"Se il collo di bottiglia è l'I / O del disco, non c'è molto che puoi fare." Questo è probabilmente vero qui, dal momento che il rapporto di compressione è già buono, ma in generale quando l'I / O è il collo di bottiglia, vale la pena esaminare l'utilizzo di più CPU per ottenere un rapporto di compressione migliore (utilizzando impostazioni di compressione diverse o un algoritmo diverso). .. non puoi davvero ridurre l '"io" (perché devi leggere tutti i dati) ma a volte puoi ridurre significativamente l' "O" :-)
psmears

1
Se dici di 7znon creare un archivio "solido" o di limitare la dimensione dei blocchi "solidi", eseguirà più thread LZMA in parallelo, IIRC. i dati del file di registro sono un caso speciale per la compressione, poiché tendono ad essere altamente ridondanti (molta somiglianza tra le righe). Vale sicuramente la pena testarlo gzip, bzip2e xzsui file di registro specifici dell'OP, piuttosto che guardare i benchmark di compressione generici per escludere qualsiasi opzione. Anche i compressori veloci sono da prendere in considerazione ( lzop, lz4, snappy).
Peter Cordes,

Il compressore LZMA preferito in questi giorni è xz. Usa tar -Jo --xz, non --lzma. .lzmaè considerato un formato di file "legacy" . Le molteplici iterazioni di formati di file per la compressione LZMA sono un po 'imbarazzanti e qualcosa che avrebbero dovuto avere ragione la prima volta. Ma AFAIK è praticamente buono ora, e .xz non sta per essere sostituito da un altro formato di file per lo stesso flusso di compressione.
Peter Cordes,

7z ha una compressione e un multi-threading eccellenti, ma a causa del formato dell'archivio (ha bisogno di un indice o forse di bug?) Non penso che possa essere usato nel mezzo di una pipeline - non utilizzerà stdin e stdout allo stesso tempo
Xen2050,

Questo è stato davvero utile e approfondito. Il mio team ha pensato che l'operazione su NFS fosse un grosso collo di bottiglia.
anu,

16

Puoi installare pigz, parallel gzip e usare tar con la compressione multi-thread. Piace:

tar -I pigz -cf file.tar.gz *

Dove è l' -Iopzione:

-I, --use-compress-program PROG
  filter through PROG

Naturalmente, se il tuo NAS non ha più core / CPU potente, sei comunque limitato dalla potenza della CPU.

La velocità del disco rigido / array su cui è in esecuzione la macchina virtuale e la compressione può essere anche un collo di bottiglia.


1
E se vuoi usare bzip2, puoi usare pbzip2o lbzip2.
Radovan Garabík,

2
Questa è la tua migliore risposta Ma prima, assicurati che la tua prima mossa sia in una posizione che si trova sullo stesso filesystem dei file originali. Altrimenti, la tua "mossa" è in realtà un byte-copia-quindi-cancella. Sullo stesso filesystem, una mossa è una riorganizzazione dei collegamenti al filesystem. Sono ordini di grandezza più veloci. Per i miei file di log che sono grandi centinaia di gigabyte, pigz ha fatto la differenza. Puoi dirlo quanti thread paralleli eseguire. Finché la tua CPU ha più core, non passerei molto tempo a investigare. Probabilmente vorrai pigz in ogni caso; puoi ottenere subito la tua velocità.
Mike S,

Una volta che stai pigiando, guarda le tue uscite htop e iostat e osserva le prestazioni del tuo sistema, se desideri approfondire ulteriormente il tuo sistema. Ma ancora una volta, non proverò più a comprimere file di grandi dimensioni senza pigz. Su un moderno sistema multicore, è semplicemente stupido non usarlo. È una vittoria così immediata, vedrai.
Mike S,

7

Di gran lunga il modo più rapido ed efficace per comprimere i dati è di generarne meno.

Che tipo di registri stai generando? 200 GB al giorno sembrano abbastanza (a meno che tu non sia google o alcuni ISP ...), considera che 1 MB di testo è di circa 500 pagine, quindi stai generando l'equivalente di 100 milioni di pagine di testo al giorno, dovrai riempire la biblioteca del congresso in una settimana.

Controlla sui tuoi dati di registro se puoi ridurli in qualche modo e ottenere comunque ciò che ti serve dai registri. Ad esempio, abbassando il livello del registro o utilizzando un formato di registro terser. Oppure, se si utilizzano i registri per le statistiche, elaborare le statistiche al volo e scaricare un file con il riepilogo, quindi filtrare i registri prima della compressione per l'archiviazione.


1
Questa è una soluzione filosofica interessante. La soluzione della maggior parte dei problemi della vita è di evitare del tutto il problema, non è vero. Questo fino a quando non si esamina attentamente il suggerimento e ci si rende conto che ci sono centinaia di persone e migliaia di approvazioni che si devono ottenere per raggiungere questo obiettivo.
anu

1
@anu Non è stato dato alcun contesto alla domanda, quindi non ne ho assunto nessuna. E potresti dirmi da dove hai ottenuto il numero 1000 di approvazioni? A me sembra che tu l'abbia appena inventato.
Emily L.,

Valuterò questo. Questa è la soluzione spesso trascurata, ma una volta notata, straordinaria per molti dei problemi della vita.
jrw32982 supporta Monica

1
Bene .. ora che non lavoro più lì, posso almeno rivelare che questo è stato un problema per Apple. Più specificamente nello stack di servizi che serve l'app store online ... quindi sì, migliaia di approvazioni sono praticamente una realtà perché hanno migliaia di microservizi e ognuno di essi produce registri che devono essere compressi e dovranno firmare quando cambiano il loro livelli di registrazione ecc ... Comunque ... abbiamo escogitato una soluzione per questo interno btw .. che è praticamente equivalente al gzip parallelo che viene scaricato su un altro microservizio.
anu

3

È possibile ridurre la quantità di compressione (in termini di spazio risparmiato) per renderla più veloce. Per cominciare, bzip2 è MOLTO più lento di gzip, anche se comprime più piccolo. Puoi anche cambiare il livello di compressione di bzip2, gzip o della maggior parte dei programmi di compressione per scambiare le dimensioni con la velocità.

Se non sei disposto a scambiare dimensioni di velocità, puoi probabilmente ottenere le stesse dimensioni o dimensioni ridotte pur ottenendo un miglioramento della velocità utilizzando un compressore che utilizza LZMA (ad esempio xz).

Troverai benchmark se cerchi, ma la tua scommessa migliore è fare alcuni test con il tuo file sul tuo hardware di destinazione.


3

Se l'unico requisito è che la compressione è veloce , consiglierei vivamente lz4 .

È utilizzato in molti luoghi in cui la velocità di compressione è più importante del rapporto di compressione (ad es. Filesystem con compressione trasparente come ZFS)


Non ne ho mai sentito parlare prima, esiste forse un programma già installato praticamente ovunque che lo utilizza, come xz?
Xen2050,
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.