web-dev-qa-db-ja.com

Hadoop:HDFSでファイルを圧縮しますか?

最近、HadoopでLZO圧縮を設定しました。 HDFSでファイルを圧縮する最も簡単な方法は何ですか?ファイルを圧縮してから元のファイルを削除したい。 IdentityMapperとLZO圧縮を使用するIdentityReducerを使用してMRジョブを作成する必要がありますか?

14
schmmd

あなたが言うように、Identityマッパーを使用するMapReduceジョブを作成することをお勧めします。その間、パフォーマンスのロードを改善するために、データをシーケンスファイルに書き出すことを検討する必要があります。シーケンスファイルをブロックレベルおよびレコードレベルの圧縮で保存することもできます。どちらも異なるタイプのレコード用に最適化されているので、Yoは何が最適かを確認する必要があります。

7
Donald Miner

私にとって、ファイルを圧縮する Hadoop Streaming ジョブを作成する方がオーバーヘッドは低くなります。

これは私が実行するコマンドです:

hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-streaming-0.20.2-cdh3u2.jar \
  -Dmapred.output.compress=true \
  -Dmapred.compress.map.output=true \
  -Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.GzipCodec \
  -Dmapred.reduce.tasks=0 \
  -input <input-path> \
  -output $OUTPUT \
  -mapper "cut -f 2"

また、通常、何か問題が発生した場合に備えて、出力を一時フォルダーに隠しておきます。

OUTPUT=/tmp/hdfs-gzip-`basename $1`-$RANDOM

もう1つ注意点として、ストリーミングジョブではレデューサーを指定していませんが、指定することはできます。これは、すべての行を強制的にソートするため、大きなファイルでは時間がかかる可能性があります。パーティショナーをオーバーライドすることでこれを回避する方法があるかもしれませんが、私はそれを理解することを気にしませんでした。これの不幸な点は、HDFSブロックを効率的に利用していない多くの小さなファイルになってしまう可能性があることです。それが Hadoop Archives を調べる理由の1つです。

21
Jeff Wu

Jeff Wuからのストリーミングコマンドと圧縮ファイルの連結により、単一の圧縮ファイルが作成されます。非Javaマッパーがストリーミングジョブに渡され、入力フォーマットがテキストの場合、ストリーミングでは、キーではなく値のみが出力されます。

hadoop jar contrib/streaming/hadoop-streaming-1.0.3.jar \
            -Dmapred.reduce.tasks=0 \
            -Dmapred.output.compress=true \
            -Dmapred.compress.map.output=true \
            -Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.GzipCodec \
            -input filename \
            -output /filename \
            -mapper /bin/cat \
            -inputformat org.Apache.hadoop.mapred.TextInputFormat \
            -outputformat org.Apache.hadoop.mapred.TextOutputFormat
hadoop fs -cat /path/part* | hadoop fs -put - /path/compressed.gz
4
Chitra

これは私が使用したものです:

/*
 * Pig script to compress a directory
 * input:   hdfs input directory to compress
 *          hdfs output directory
 * 
 * 
 */

set output.compression.enabled true;
set output.compression.codec org.Apache.hadoop.io.compress.BZip2Codec;

--comma seperated list of hdfs directories to compress
input0 = LOAD '$IN_DIR' USING PigStorage();

--single output directory
STORE input0 INTO '$OUT_DIR' USING PigStorage(); 

LZOではないので少し遅いかもしれません。

4
dranxo

@Chitra評判の問題でコメントできない

1つのコマンドのすべてを以下に示します。2番目のコマンドを使用する代わりに、1つの圧縮ファイルに直接縮小できます。

hadoop jar share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar \
        -Dmapred.reduce.tasks=1 \
        -Dmapred.output.compress=true \
        -Dmapred.compress.map.output=true \
        -Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.BZip2Codec \
        -input /input/raw_file \
        -output /archives/ \
        -mapper /bin/cat \
        -reducer /bin/cat \
        -inputformat org.Apache.hadoop.mapred.TextInputFormat \
        -outputformat org.Apache.hadoop.mapred.TextOutputFormat

したがって、圧縮ファイルを1つだけにすることで、多くのスペースを確保できます。

たとえば、10MBの4つのファイルがあるとします(プレーンテキスト、JSON形式)

マップのみで650 KBのファイルが4つ表示されます。マップして縮小すると、1.05 MBのファイルが1つあります。

4
Eldinea

私はこれが古いスレッドであることを知っていますが、このスレッドをフォローしている人(私のように)がいる場合、次の2つの方法のいずれかが各行の終わりにtab(\ t)文字を与えることを知っていると便利です

 hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-streaming-0.20.2-cdh3u2.jar \
      -Dmapred.output.compress=true \
      -Dmapred.compress.map.output=true \
      -Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.GzipCodec \
      -Dmapred.reduce.tasks=0 \
      -input <input-path> \
      -output $OUTPUT \
      -mapper "cut -f 2"


hadoop jar share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar \
        -Dmapred.reduce.tasks=1 \
        -Dmapred.output.compress=true \
        -Dmapred.compress.map.output=true \
        -Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.BZip2Codec \
        -input /input/raw_file \
        -output /archives/ \
        -mapper /bin/cat \
        -reducer /bin/cat \
        -inputformat org.Apache.hadoop.mapred.TextInputFormat \
        -outputformat org.Apache.hadoop.mapred.TextOutputFormat

これから hadoop-streaming.jarは各行の終わりにx'09 'を追加します 、修正を見つけ、使用する区切り文字を再指定するために次の2つのパラメーターを設定する必要があります(私の場合は、 )

 -Dstream.map.output.field.separator=, \
 -Dmapred.textoutputformat.separator=, \

実行する完全なコマンド

hadoop jar <HADOOP_HOME>/jars/hadoop-streaming-2.6.0-cdh5.4.11.jar \
        -Dmapred.reduce.tasks=1 \
        -Dmapred.output.compress=true \
        -Dmapred.compress.map.output=true \
 -Dstream.map.output.field.separator=, \
 -Dmapred.textoutputformat.separator=, \
        -Dmapred.output.compression.codec=org.Apache.hadoop.io.compress.Lz4Codec \
        -input file:////home/admin.kopparapu/accenture/File1_PII_Phone_part3.csv \
        -output file:///home/admin.kopparapu/accenture/part3 \
 -mapper /bin/cat \
        -reducer /bin/cat \
        -inputformat org.Apache.hadoop.mapred.TextInputFormat \
        -outputformat org.Apache.hadoop.mapred.TextOutputFormat
0
Naga