阅读 121

HDFS 07 - HDFS 性能调优之 合并小文件

HDFS 07 - HDFS 性能调优之 合并小文件

1 - 为什么要合并小文件

HDFS 擅长存储大文件

我们知道,HDFS 中,每个文件都有各自的元数据信息,如果 HDFS 中有大量的小文件,就会导致元数据爆炸,集群管理的元数据的内存压力会非常大。

所以在项目中,把小文件合并成大文件,是一种很有用也很常见的优化方法。

2 - 合并本地的小文件,上传到 HDFS

将本地的多个小文件,上传到 HDFS,可以通过 HDFS 客户端的 appendToFile 命令对小文件进行合并。

在本地准备2个小文件:

# user1.txt 内容如下:1,tom,male,16
2,jerry,male,10# user2.txt 内容如下:101,jack,male,19
102,rose,female,18

合并方式:

hdfs dfs -appendToFile user1.txt user2.txt /test/upload/merged_user.txt

合并后的文件内容:

3 - 合并 HDFS 的小文件,下载到本地

可以通过 HDFS 客户端的 getmerge 命令,将很多小文件合并成一个大文件,然后下载到本地。

# 先上传小文件到 HDFS:hdfs dfs -put user1.txt user2.txt /test/upload# 下载,同时合并:hdfs dfs -getmerge /test/upload/user*.txt ./merged_user.txt

下载、合并后的文件内容:

4 - 通过 Java API 实现文件合并和上传

代码如下(具体测试项目,可到 我的 GitHub 查看):

@Testpublic void testMergeFile() throws Exception {    // 获取分布式文件系统
    FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop:9000"), new Configuration(), "healchow");
    FSDataOutputStream outputStream = fileSystem.create(new Path("/test/upload/merged_by_java.txt"));    // 获取本地文件系统
    LocalFileSystem local = FileSystem.getLocal(new Configuration());    // 通过本地文件系统获取文件列表,这里必须指定路径
    FileStatus[] fileStatuses = local.listStatus(new Path("file:/Users/healchow/bigdata/test"));    for (FileStatus fileStatus : fileStatuses) {        // 创建输入流,操作完即关闭
        if (fileStatus.getPath().getName().contains("user")) {
            FSDataInputStream inputStream = local.open(fileStatus.getPath());
            IOUtils.copy(inputStream, outputStream);
            IOUtils.closeQuietly(inputStream);
        }
    }    // 关闭输出流和文件系统
    IOUtils.closeQuietly(outputStream);
    local.close();
    fileSystem.close();
}

合并的结果,和通过命令合并的完全一致:



版权声明

作者:瘦风(https://healchow.com)

出处:博客园-瘦风的南墙(https://www.cnblogs.com/shoufeng)


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐