我将多个小文件放入我的输入目录,我希望将其合并到一个文件中,而不使用本地文件系统或编写mapred。有没有办法可以使用hadoof fs命令或Pig?
谢谢!
答案 0 :(得分:22)
为了保持网格上的所有内容,使用hadoop流式传输,使用单个reducer和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
答案 1 :(得分:15)
hadoop fs -getmerge <dir_of_input_files> <mergedsinglefile>
答案 2 :(得分:7)
好吧......我想出了一种使用hadoop fs
命令的方式 -
hadoop fs -cat [dir]/* | hadoop fs -put - [destination file]
当我测试它时,它有用吗......人们可以想到的任何陷阱?
谢谢!
答案 3 :(得分:2)
如果设置fuse以将HDFS安装到本地目录,则输出可以是挂载的文件系统。
例如,我将HDFS本地安装到/mnt/hdfs
。我运行以下命令,效果很好:
hadoop fs -getmerge /reports/some_output /mnt/hdfs/reports/some_output.txt
当然,使用fuse将HDFS挂载到本地目录还有其他原因,但这对我们来说是一个很好的副作用。
答案 4 :(得分:1)
您可以使用HDFS 0.21中的新工具HDFSConcat执行此操作,而不会产生副本费用。
答案 5 :(得分:1)
如果您在Hortonworks群集中工作并希望将HDFS位置中存在的多个文件合并到一个文件中,那么您可以运行&#39; hadoop-streaming-2.7.1.2.3.2.0-2950.jar&#39; jar运行单个reducer并将合并的文件放入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位置
答案 6 :(得分:0)
所有解决方案都相当于做
hadoop fs -cat [dir]/* > tmp_local_file
hadoop fs -copyFromLocal tmp_local_file
它只意味着本地m / c I / O处于数据传输的关键路径上。
答案 7 :(得分:0)
从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')