合并hdfs文件

JoR*_*oot 19 hadoop hdfs

我在HDFS中有1000多个文件,其命名约定1_fileName.txtN_fileName.txt.每个文件的大小为1024 MB.我需要将这些文件合并为一个(HDFS)并保持文件的顺序.说5_FileName.txt应该只追加4_fileName.txt

执行此操作的最佳和最快方法是什么.

是否有任何方法可以在不复制数据节点之间的实际数据的情况下执行此合并?例如:获取此文件的块位置并在Namenode中创建具有这些块位置的新条目(FileName)?

Chr*_*ite 18

没有有效的方法,您需要将所有数据移动到一个节点,然后再移回HDFS.

执行此操作的命令行scriptlet可能如下所示:

hadoop fs -text *_fileName.txt | hadoop fs -put - targetFilename.txt
Run Code Online (Sandbox Code Playgroud)

这将把所有匹配glob的文件捕获到标准输出,然后你将该流传递给put命令并将流输出到名为targetFilename.txt的HDFS文件

你遇到的唯一问题是你已经去过的文件名结构 - 如果你有固定的宽度,zeropadded数字部分会更容易,但在它的当前状态你会得到一个意想不到的lexigraphic顺序(1,10,100,1000 ,11,110等)而不是数字顺序(1,2,3,4等).您可以通过修改scriptlet来解决此问题:

hadoop fs -text [0-9]_fileName.txt [0-9][0-9]_fileName.txt \
    [0-9][0-9[0-9]_fileName.txt | hadoop fs -put - targetFilename.txt
Run Code Online (Sandbox Code Playgroud)

  • text和cat是相同的,但是文本也适用于压缩文件和序列文件 (3认同)

Dmi*_*try 12

有一个执行此操作的API方法org.apache.hadoop.fs.FileUtil.copyMerge:

public static boolean copyMerge(
                    FileSystem srcFS,
                    Path srcDir,
                    FileSystem dstFS,
                    Path dstFile,
                    boolean deleteSource,
                    Configuration conf,
                    String addString)
Run Code Online (Sandbox Code Playgroud)

srcDir按字母顺序读取所有文件,并将其内容附加到dstFile.

  • 看[来源](http://grepcode.com/file/repository.cloudera.com/content/repositories/releases/com.cloudera.hadoop/hadoop-core/0.20.2-320/org/apache/hadoop /fs/FileUtil.java#FileUtil.copyMerge%28org.apache.hadoop.fs.FileSystem%2Corg.apache.hadoop.fs.Path%2Corg.apache.hadoop.fs.FileSystem%2Corg.apache.hadoop.fs.Path %2Cboolean%2Corg.apache.hadoop.conf.Configuration%2Cjava.lang.String%29),这仍然会将所有数据拉到一个节点,然后再将其发送回HDFS. (3认同)

use*_*660 5

如果你可以使用火花.可以这样做

sc.textFile("hdfs://...../part*).coalesce(1).saveAsTextFile("hdfs://...../filename)
Run Code Online (Sandbox Code Playgroud)

希望这是有效的,因为spark以分布式方式工作,你不必将文件复制到一个节点.虽然只是一个小心,但如果文件非常大,火花中的合并文件可能会很慢.