我将多个小文件放入我的输入目录中,我想在不使用本地文件系统或编写 mapreds 的情况下将它们合并到一个文件中。有没有办法使用 hadoof fs 命令或 Pig 来做到这一点?
谢谢!
我将多个小文件放入我的输入目录中,我想在不使用本地文件系统或编写 mapreds 的情况下将它们合并到一个文件中。有没有办法使用 hadoof fs 命令或 Pig 来做到这一点?
谢谢!
为了保持网格上的所有内容,使用带有单个 reducer 的 hadoop 流,并将 cat 作为 mapper 和 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=true \ -Dmapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec
hadoop fs -getmerge <dir_of_input_files> <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 位置中存在的多个文件合并到一个文件中,那么您可以运行运行单个 reducer 的“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
您可以从 Get hadoop streaming jar 下载此 jar
如果您正在编写 spark 作业并希望获得一个合并文件以避免创建多个 RDD 和性能瓶颈,请在转换您的 RDD 之前使用这段代码
sc.textFile("hdfs://...../part*).coalesce(1).saveAsTextFile("hdfs://...../filename)
这会将所有零件文件合并为一个并再次将其保存到 hdfs 位置
所有的解决方案都相当于做一个
hadoop fs -cat [dir]/* > tmp_local_file
hadoop fs -copyFromLocal tmp_local_file
这仅意味着本地 m/c I/O 处于数据传输的关键路径上。
从 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')