【发布时间】:2011-04-02 16:08:49
【问题描述】:
我将多个小文件放入我的输入目录中,我想在不使用本地文件系统或编写 mapreds 的情况下将它们合并到一个文件中。有没有办法我可以使用 hadoof fs 命令或 Pig 来做到这一点?
谢谢!
【问题讨论】:
-
如果您的问题已得到解答,您应该接受答案。
标签: hadoop apache-pig
我将多个小文件放入我的输入目录中,我想在不使用本地文件系统或编写 mapreds 的情况下将它们合并到一个文件中。有没有办法我可以使用 hadoof fs 命令或 Pig 来做到这一点?
谢谢!
【问题讨论】:
标签: hadoop apache-pig
为了将所有内容保持在网格上,请使用带有单个 reducer 的 hadoop 流,并将 cat 作为映射器和 reducer(基本上是一个 noop) - 使用 MR 标志添加压缩。
hadoop jar \
$HADOOP_PREFIX/share/hadoop/tools/lib/hadoop-streaming.jar \<br>
-Dmapred.reduce.tasks=1 \
-Dmapred.job.queue.name=$QUEUE \
-input "$INPUT" \
-output "$OUTPUT" \
-mapper cat \
-reducer cat
如果你想压缩添加
-Dmapred.output.compress=真\
-Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec
【讨论】:
hadoop fs -getmerge <dir_of_input_files> <mergedsinglefile>
【讨论】:
mergedsinglefile 是本地的,不是分布式的
好的...我想出了一个使用hadoop fs 命令的方法 -
hadoop fs -cat [dir]/* | hadoop fs -put - [destination file]
当我测试它时它起作用了……有什么可以想到的陷阱吗?
谢谢!
【讨论】:
如果您设置 fuse 以将 HDFS 挂载到本地目录,那么您的输出可以是挂载的文件系统。
例如,我在本地将我们的 HDFS 挂载到 /mnt/hdfs。我运行以下命令,效果很好:
hadoop fs -getmerge /reports/some_output /mnt/hdfs/reports/some_output.txt
当然,使用 fuse 将 HDFS 挂载到本地目录还有其他原因,但这对我们来说是一个很好的副作用。
【讨论】:
您可以使用 HDFS 0.21 中的新工具 HDFSConcat 来执行此操作,而不会产生复制成本。
【讨论】:
如果您在 Hortonworks 集群中工作并希望将 HDFS 位置中的多个文件合并到一个文件中,那么您可以运行运行单个减速器的“hadoop-streaming-2.7.1.2.3.2.0-2950.jar”jar并将合并后的文件放入 HDFS 输出位置。
$ hadoop jar /usr/hdp/2.3.2.0-2950/hadoop-mapreduce/hadoop-streaming-2.7.1.2.3.2.0-2950.jar \
-Dmapred.reduce.tasks=1 \
-input "/hdfs/input/dir" \
-output "/hdfs/output/dir" \
-mapper cat \
-reducer cat
您可以从以下位置下载此 jar Get hadoop streaming jar
如果您正在编写 spark 作业并希望获得一个合并文件以避免创建多个 RDD 和性能瓶颈,请在转换您的 RDD 之前使用这段代码
sc.textFile("hdfs://...../part*).coalesce(1).saveAsTextFile("hdfs://...../filename)
这会将所有部分文件合并为一个并再次保存到 hdfs 位置
【讨论】:
从 Apache Pig 的角度解决这个问题,
通过 Pig 合并两个具有相同架构的文件,可以使用 UNION 命令
A = load 'tmp/file1' Using PigStorage('\t') as ....(schema1)
B = load 'tmp/file2' Using PigStorage('\t') as ....(schema1)
C = UNION A,B
store C into 'tmp/fileoutput' Using PigStorage('\t')
【讨论】:
所有的解决方案都相当于做了一个
hadoop fs -cat [dir]/* > tmp_local_file
hadoop fs -copyFromLocal tmp_local_file
仅表示本地 m/c I/O 处于数据传输的关键路径上。
【讨论】: