Hadoop HDFS 小文件合并

Hadoop HDFS 小文件合并

HDFS的小文件合并

由于Hadoop擅长存储大文件,因为大文件的元数据信息比较少,如果Hadoop集群当中有大量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理。

在我们的hdfs 的shell命令模式下,可以通过命令行将很多的hdfs文件合并成一个大文件下载到本地,命令如下:

cd /export/servers
hdfs dfs -getmerge /config/*.xml  ./hello.xml
www.zeeklog.com  - Hadoop HDFS 小文件合并

既然可以在下载的时候将这些小文件合并成一个大文件一起下载,那么肯定就可以在上传的时候将小文件合并到一个大文件里面去
代码如下:

www.zeeklog.com  - Hadoop HDFS 小文件合并


www.zeeklog.com  - Hadoop HDFS 小文件合并


首先我在E盘创建了个test文件夹,里边有个123.txt,我把它复制粘贴了4份,
一共5份,每份的内容都是111111111

www.zeeklog.com  - Hadoop HDFS 小文件合并


然后运行如下java代码

import org.apache.commons.io.IOUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;

import java.net.URI;
import java.util.Arrays;

public class demo08 {
    public static void main(String[] args) throws Exception{
        //获取分布式文件系统
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.100.201:8020"),new Configuration(),"root");
        FSDataOutputStream outputStream = fileSystem.create(new Path("/bigfile.xml"));
        //获取本地文件系统
        LocalFileSystem local = FileSystem.getLocal(new Configuration());
        //通过本地文件系统获取文件列表为一个集合
        FileStatus[] fileStatuses = local.listStatus(new Path("file:///E:\\test"));
        System.out.println(Arrays.toString(fileStatuses));
        for (FileStatus fileStatus : fileStatuses) {
            FSDataInputStream inputStream = local.open(fileStatus.getPath());
            IOUtils.copy(inputStream,outputStream);
            IOUtils.closeQuietly(inputStream);
        }
        IOUtils.closeQuietly(outputStream);
        local.close();
        fileSystem.close();


    }
}

运行完后,查看hdfs里的文件

hadoop fs -ls /
www.zeeklog.com  - Hadoop HDFS 小文件合并


发现bigfile上传完了,查看一下里边的内容

hadoop fs -cat /bigfile.xml
www.zeeklog.com  - Hadoop HDFS 小文件合并


成功了,5个文件中的内容被合并到一起了。