Hadoop:在HDFS中压缩文件?

时间:2011-08-22 20:17:00

标签: compression hadoop

我最近在Hadoop中设置了LZO压缩。在HDFS中压缩文件的最简单方法是什么?我想压缩文件,然后删除原始文件。我应该使用IdentityMapper和使用LZO压缩的IdentityReducer创建MR作业吗?

7 个答案:

答案 0 :(得分:20)

对我来说,编写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

另外一点,我没有在流媒体工作中指定减速器,但你当然可以。它将强制对所有行进行排序,这对于大文件可能需要很长时间。可能有一种方法可以通过覆盖分区来解决这个问题,但我并没有费心去解决这个问题。不幸的是,您可能最终得到许多不能有效利用HDFS块的小文件。这是调查Hadoop Archives

的一个原因

答案 1 :(得分:7)

我建议您编写MapReduce作业,正如您所说,只使用Identity mapper。在您使用它时,您应该考虑将数据写入序列文件以提高性能加载。您还可以在块级和记录级压缩中存储序列文件。你应该看看什么最适合你,因为两者都针对不同类型的记录进行了优化。

答案 2 :(得分:4)

来自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

答案 3 :(得分:4)

这就是我用过的:

/*
 * 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 :(得分:4)

@Chitra 由于声誉问题,我无法发表评论

以下是一个命令中的所有内容:您可以直接缩减为一个压缩文件,而不是使用第二个命令

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

因此,通过只有一个压缩文件

可以获得大量空间

例如,假设我有4个10MB的文件(它是纯文本,JSON格式化)

地图只给了我4个650 KB的文件 如果我映射并减少我有1个1.05 MB的文件

答案 5 :(得分:0)

我知道这是旧线程,但是如果跟随此线程的任何人(如我),了解以下两种方法中的任何一种都会在每个方法的末尾给您一个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 adds x'09' at the end of each line中,我找到了解决方法,我们需要设置以下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

答案 6 :(得分:-4)

好吧,如果你压缩一个文件,你可以节省一些空间,但你不能真正使用Hadoop的能力处理该文件,因为解压缩必须由一个Map任务顺序完成。如果你有很多文件,那就是Hadoop Archive,但我不确定它是否包含任何类型的压缩。我可以想到压缩的主要用例是压缩要发送到Reduced的地图输出(节省网络I / O)。

哦,为了更完整地回答你的问题,你可能需要实现自己的RecordReader和/或InputFormat,以确保整个文件被单个Map任务读取,并且它还使用了正确的解压缩过滤器。 / p>