HDFS并不擅长存储小文件,因为每个文件最少一个block,每个block的元数据都会在NameNode占用内存,如果存在大量的小文件,它们会吃掉NameNode节点的大量内存。
Hadoop Archives可以有效的处理以上问题,它可以把多个文件归档成为一个文件,归档成一个文件后还可以透明的访问每一个文件。
hadoop archive -archiveName name -p <parent> <src>* <dest>
hadoop archive -archiveName test.har -p /config /outputdir
首先我们来看下创建好的har文件。使用如下的命令:
hadoop fs -ls /outputdir/test.har
hadoop fs -cat /outputdir/test.har/part-0
archive作为文件系统层暴露给外界。
所以所有的fs shell命令都能在archive上运行,但是要使用不同的URI。
Hadoop Archives的URI是:
har://scheme-hostname:port/archivepath/fileinarchive
scheme-hostname格式为hdfs-域名:端口,如果没有提供scheme-hostname,它会使用默认的文件系统。这种情况下URI是这种形式:
har:///archivepath/fileinarchive
如果用har uri去访问的话,索引、标识等文件就会隐藏起来,只显示创建档案之前的原文件:
查看归档文件中的小文件,使用har uri
hadoop fs -ls har://hdfs-node1:8020/outputdir/test.har
查看归档文件中的小文件,不使用har uri
hadoop fs -ls har:///outputdir/test.har
查看har归档文件中小文件的内容
hadoop fs -cat har:///outputdir/test.har/core-site.xml
hadoop fs -mkdir /config2
hadoop fs -cp har:///outputdir/test.har/* /config2
FileSystem fileSystem = FileSystem.get(new URI("hdfs://node1:8020"), new Configuration());
HarFileSystem harFileSystem = new HarFileSystem(fileSystem);
harFileSystem.initialize(new URI("har://hdfs-node1:/output/archive/config.har"), new Configuration());
FileStatus[] iterator = harFileSystem.listStatus(new Path("/part-0"));
for (FileStatus fileStatus : iterator) {
System.out.println(fileStatus.getPath());
}
fileSystem.close();
因篇幅问题不能全部显示,请点此查看更多更全内容