【发布时间】:2011-08-22 20:16:59
【问题描述】:
我最近在 Hadoop 中设置了 LZO 压缩。在 HDFS 中压缩文件的最简单方法是什么?我想压缩一个文件,然后删除原始文件。我是否应该使用使用 LZO 压缩的 IdentityMapper 和 IdentityReducer 创建 MR 作业?
【问题讨论】:
标签: compression hadoop
我最近在 Hadoop 中设置了 LZO 压缩。在 HDFS 中压缩文件的最简单方法是什么?我想压缩一个文件,然后删除原始文件。我是否应该使用使用 LZO 压缩的 IdentityMapper 和 IdentityReducer 创建 MR 作业?
【问题讨论】:
标签: compression hadoop
对我来说,编写 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
的原因之一【讨论】:
cut -f 2 仅输出值。
我建议您编写一个 MapReduce 作业,正如您所说,它只使用身份映射器。当您使用它时,您应该考虑将数据写入序列文件以提高性能加载。您还可以将序列文件存储在块级和记录级压缩中。你应该看看什么最适合你,因为两者都针对不同类型的记录进行了优化。
【讨论】:
来自 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
【讨论】:
tab 字符
这是我用过的:
/*
* 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,所以可能会慢一些。
【讨论】:
@奇特拉 由于声誉问题,我无法发表评论
这是一个命令中的所有内容:您可以直接将其缩减为一个压缩文件,而不是使用第二个命令
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 的文件
【讨论】:
我知道这是旧线程,但如果有人关注此线程(如我),知道以下两种方法中的任何一种都会在每行末尾为您提供 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
【讨论】:
好吧,如果您压缩单个文件,您可能会节省一些空间,但您不能真正使用 Hadoop 的功能来处理该文件,因为解压缩必须由单个 Map 任务顺序完成。如果您有很多文件,则有Hadoop Archive,但我不确定它是否包含任何类型的压缩。我能想到的主要压缩用例是压缩 Maps 的输出以发送到 Reduces(节省网络 I/O)。
哦,为了更完整地回答您的问题,您可能需要实现自己的 RecordReader 和/或 InputFormat 以确保整个文件被单个 Map 任务读取,并且它使用了正确的解压缩过滤器。
【讨论】: