Hadoop HDFS (4) Hadoop Archives,hadoophdfs


用HDFS存储小文件是不经济的,因为每个文件都存在一个block里,每个block的metadata又在namenode的内存里存着,所以,大量的小文件,会吃掉大量的namenode的内存。(注意:一个小文件占用一个block,但是这个block的大小不是设定的值,比如设定每个block是128M,但是一个1M的文件存在一个block里,实际占用的datanode的硬盘大小是1M,而不是128M。所以这里说的不经济是指占用大量namenode的内存资源,而不是说占用大量datanode的磁盘资源。)
Hadoop Archives(HAR文件)是一个文件打包工具,它把文件打包放进HDFS,以更加有效地利用block,从而降低namenode的内存使用。同时,Hadoop Archives还允许客户端透明访问HAR包里的文件,像访问文件夹里的文件一样方便,更重要的是,HAR文件还可以作为MapReduce的输入。

Hadoop Archives的使用方法

$hadoop fs -ls -R /user/norris/ 列出/user/norris/目录下的所有文件,-R表示递归列出子目录里的文件。 然后我们可以使用下面命令: $hadoop archive -archiveName files.har -p /user/norris/ /user/norris/har/ 这个命令把/user/norris/目录下的所有内容打成files.har包放在/user/norris/har/下。 -p表示父目录(parent)。 之后使用 $hadoop fs -ls /user/norris/har/ 查看/user/norris/har/目录下生成一个files.har文件。 $hadoop fs -ls /user/norris/har/files.har 可以看到files.har包由两个index文件和一组part文件组成。 part文件就是把所有文件内容拼接在一起,index文件存储文件起始位置的偏移量和文件长度。 如果要查看har文件的内容,可以用URI Scheme har来查看: $hadoop fs -ls -R har:///user/norris/har/files.har 列出har里的文件和目录 HAR文件系统位于底层文件系统(HDFS)之上。
删除一个har文件要使用: $hadoop fs -rm -R /user/norris/har/files.har 要用-R选项,因为在底层文件系统看来,.har文件其实是一个目录。

Hadoop Archives的使用限制

1. 创建一个HAR需要跟源文件相同大小的空间,所以,在准备创建一个HAR之前,要保证有相同大小的磁盘空间,创建之后,可以删除原来的文件。目录Hadoop Archives只打包,不压缩。 2. HAR文件一旦创建不可修改,不能向其中增加或删除文件。在实际使用中,一般对于一旦生成就不再更改的文件做定期的archive,比如,每天把当天生成的日志文件打成一个包。 3. 之前提到HAR文件可以作为MapReduce的输入,但是多个小文件打成包输入给MapReduce,并不比单独小文件输入给MapReduce更有效率,关于解决众多小文件输入的效率问题,后面要讨论其他解决方案。 4. 如果namenode的内存不够用了,在考虑减少系统中的大量小文件之后,应该考虑HDFS Federation。我们之前提到过:http://blog.csdn.net/norriszhang/article/details/39178041







怎从hadoop的Hdfs上查询文件

A1.该索引叫FsImage, 但没有对外提供api, 参考 附录的链接1
整个文件系统的名字空间,包括数据块到文件的映射、文件的属性等,都存储在一个称为FsImage的文件中,这个文件也是放在Namenode所在的本地文件系统上。

A2. FS Shell, 详细请参考链接2
1)hadoop fs -ls
功能跟shell 的 ls 命令相同
2)hadoop fs -lsr
ls命令的递归版本。类似于Unix中的ls -R。

如果要实现复杂的查找功能,可以考虑用下述方式
hadoop fs -lsr / | awk/sed/grep .....

链接1:FsImage/EditLog的官方说明
hadoop.apache.org/...%8C%96

链接2:HDFS shell
hadoop.apache.org/...tml#ls
 

怎判断hdfs(hadoop)上的路径是文件还是目录

先用hdfsGetPathInfo 得到一个hdfsFileInfo类型的结构体,
get_real_path(dsh, s, real_path);
hdfsFileInfo * pt_hdfs_file_info = hdfsGetPathInfo(hdfs,real_path);//
这个结构体中有个kind属性,就是来区分是文件还是目录
typedef struct {
tObjectKind mKind; /* file or directory */
char *mName; /* the name of the file */
tTime mLastMod; /* the last modification time for the file in seconds */
tOffset mSize; /* the size of the file in bytes */
short mReplication; /* the count of replicas */
tOffset mBlockSize; /* the block size for the file */
char *mOwner; /* the owner of the file */
char *mGroup; /* the group associated with the file */
short mPermissions; /* the permissions associated with the file */
tTime mLastAccess; /* the last access time for the file in seconds */
} hdfsFileInfo;
 

相关内容