2013-02-11 27 views
12

Abbiamo capito un po 'troppo tardi che archiviare i nostri file in formato GZip per l'elaborazione Hadoop non è una grande idea. GZip non è scindibile, e per riferimento, qui ci sono i problemi che non voglio ripetere:La migliore compressione splittabile per input Hadoop = bz2?

La mia domanda è: BZip2 è la migliore compressione di archiviazione che consentirà di elaborare un singolo file di archivio in parallelo da Hadoop? Gzip non è assolutamente, e dalla mia lettura LZO ha alcuni problemi.

risposta

15

BZIP2 è divisibile in Hadoop - fornisce rapporto di compressione molto buono ma dal tempo e dalle prestazioni della CPU non fornisce risultati ottimali, poiché la compressione consuma molta CPU.

LZO è divisibile in Hadoop - sfruttando hadoop-lzo file LZO avete scindibile compressi. È necessario disporre di file esterni .lzo.index per poterli elaborare in parallelo. La libreria fornisce tutti i mezzi per generare questi indici in modo locale o distribuito.

LZ4 è divisibile in Hadoop - sfruttando hadoop-4mc file 4MC avete scindibile compressi. Non è necessario alcun indicizzazione esterna e si possono generare archivi con lo strumento da riga di comando fornito o da codice Java/C, dentro o fuori hadoop. 4mc rende disponibili su hadoop LZ4 a qualsiasi livello di velocità/rapporto di compressione: dalla modalità veloce fino a 500 MB/s di velocità di compressione fino alle modalità alto/ultra fornendo un rapporto di compressione maggiore, quasi paragonabile a quello di GZIP.

+4

Preferisco LZ4 me stesso in questi giorni. –

+1

sorpreso che hai lasciato fuori Zlib. – nikk

2

Ecco cinque modi con gzip, tre che richiedono un indice, due no.

È possibile creare un indice per qualsiasi file gzip, cioè non appositamente costruito, come fatto da zran.c. Quindi puoi iniziare la decompressione ai limiti dei blocchi. L'indice include 32 KB di cronologia dati non compressi in ogni punto di ingresso.

Se si sta costruendo il file gzip, allora può essere creato con punti di ingresso periodici il cui indice non ha bisogno della cronologia non compressa in quei punti di ingresso, creando un indice più piccolo. Questo viene fatto con l'opzione Z_FULL_FLUSH su deflate() in zlib.

Si potrebbe anche fare un Z_SYNC_FLUSH seguito da un Z_FULL_FLUSH in corrispondenza di ciascun punto, che inserirà due indicatori. Quindi è possibile cercare il modello a nove byte 00 00 ff ff 00 00 00 ff ff per trovarli. Non è diverso dal cercare l'indicatore di sei byte nei file bzip2, tranne che un falso positivo è molto meno probabile con nove byte. Quindi non è necessario un file di indice separato.

Entrambi gzip e xz supportano la concatenazione semplice. Ciò consente di preparare facilmente un archivio per la decompressione parallela in un altro modo. In breve:

gzip <a> a.gz 
gzip <b> b.gz 
cat a.gz b.gz > c.gz 
gunzip <c.gz> c 
cat a b | cmp - c 

comporterà il confronto successivo.

È quindi possibile comprimere semplicemente in blocchi della dimensione desiderata e concatenare i risultati. Salva un indice agli scostamenti all'inizio di ogni flusso gzip. Decomprimere da queste compensazioni. Puoi scegliere la dimensione dei blocchi a tuo piacimento, a seconda dell'applicazione. Se li rendi troppo piccoli, tuttavia, la compressione verrà influenzata.

Con una semplice concatenazione di file gzip, è possibile anche rinunciare all'indice se si rende ogni pezzo un formato non compresso fisso. Quindi ciascun blocco termina con gli stessi quattro byte, la lunghezza non compressa nell'ordine little-endian, ad es. 00 00 10 00 per 1 blocco MiB, seguito da 1f 8b 08 dal chunk successivo, che è l'inizio di un'intestazione gzip. Quel marcatore a sette byte può quindi essere cercato esattamente come il marcatore bzip2, sebbene di nuovo con una minore probabilità di falsi positivi.

Lo stesso potrebbe essere fatto con i file xz concatenati, la cui intestazione è i sette byte: fd 37 7a 58 5a 00 00.

+0

Grazie! Come è possibile preparare i file gzip/bzip2 e renderli divisibili con i punti di ingresso? – Suman

+0

Vedere la risposta aggiornata. –

+0

Suggerimento: poiché non ho trovato hadoop fs -bzcat, uso invece: hadoop fs -cat /FILENAME.bz | bzcat | meno – xgMz

4

Non considero l'altra risposta corretta, bzip2 in base a questo:

http://comphadoop.weebly.com/

è divisibile. LZO è anche se indicizzato.

Quindi la risposta è sì, se si desidera utilizzare più mapper di quanti file si hanno, quindi si vorrà utilizzare bzip2.

Per fare questo, si potrebbe scrivere un lavoro MR semplice per leggere i dati, allora basta scrivere di nuovo, è quindi necessario per essere sicuri di impostare mapred.output.compression.codec a org.apache.hadoop.io.compress.BZip2Codec

+1

Vorrei andare con questa risposta, ma sarebbe molto meglio se ci deste anche il COME: Come posso creare file bz2 indicizzati? – Gavriel

+0

@Gavriel Non so come creare * LZO indicizzato *, ma aggiornerò la mia risposta per spiegare brevemente come comprimere su bzip2. – samthebest

+0

(Bene, scrivo il mio output tramite compressione gzip, perché è ciò che può leggere RedShift), ma qualsiasi file bzip2 corretto deve essere inserito come input o devo passare qualche parametro speciale per avere i blocchi/gli indici? – Gavriel