下面我们来分析FSDirectory。其实分析FSDirectory 最好的地方,应该是介绍完INode*以后,FSDirectory 在INode*的基础
上,保存了HDFS 的文件目录状态。系统加载FSImage 时,FSImage 会在FSDirectory 对象上重建文件目录状态,HDFS 文件目录
状态的变化,也由FSDirectory 写日志,同时,它保存了文件名数据块的映射关系。
FSDirectory 只有很少的成员变量,如下:
finfinal FSNamesystem namesystem;
final INodeDirectoryWithQuota rootDir;
FSIma ge fsImage;
boolean ready = false;
其中,namesystem,fsImage 是指向FSNamesystem 对象和FSImage 对象的引用,rootDir 是文件系统的根,ready 初值为false,
当系统成功加载FSImage 以后,ready 会变成true,FSDirectory 的使用者就可以调用其它FSDirectory 功能了。
FSDirectory 中剩下的,就是一堆的方法(我们不讨论和MBean 相关的类,方法和过程)。
loadFSImage 用于加载目录树结构,它会去调用FSImage 的方法,完成持久化信息的导入以后,它会把成员变量ready 置为true。
系统调用loadFSImage 是在FSNamesystem.java 的initialize 方法,那是系统初始化重要的一步。
addFile 用于创建文件或追加数据时创建INodeFileUnderConstruction,下图是它的Call Hierachy 图:
addFile 首先会试图在系统中创建到文件的路径,如果文件为/home/hadoop/Hadoop.tar,addFile 会调用mkdirs(创建路径为
/home/hadoop,这也会涉及到一系列方法),保证文件路径存在,然后创建INodeFileUnderConstruction 节点,并把该节点加
到目录树中(通过addNode,也是需要调用一系列方法),如果成功,就写操作日志(logOpenFile)。
unprotectedAddFile 也用于在系统中创建一个目录或文件(非UnderConstruction),如果是文件,还会建立对应的block。
FSDirectory 中还有好几个unprotected*方法,它们不检查成员变量ready,不写日志,它们大量用于loadFSEdits 中(这个
时候ready 当然是false,而且因为正在恢复日志,也不需要写日志)。
addToParent 添加一个INode 到目录树中,并返回它的上一级目录,它的实现和unprotectedAddFile 是类似的。
persistBlocks 比较有意思,用于往日志里记录某inode 的block 信息,其实并没有一个对应于persistBlocks 的写日志方法,
它用的是logOpenFile。这个大家可以去检查一下logOpenFile 记录的信息。closeFile 对应了logCloseFile。
addBlock 和removeBlock 对应,用于添加/删除数据块信息,同时它们还需要更新FSNamesystem.java 中对应的信息。
unprotectedRenameTo 和renameTo 实现了UNIX 的mv 命令,主要的功能都在unprotectedRenameTo 中完成,复杂的地方在于对
各种各样情况的讨论。
setReplication 和unprotectedSetReplication 用于更新数据块的副本数,很简单的方法,注意,改变产生的对数据块的删除
/复制是在FSNamesystem.java 中实现。
setPermission,unprotectedSetPermission,setOwner 和unprotectedSetOwner 都是简单的方法。
Delete 和unprotectedDelete 又是一对方法,删除如果需要删除数据块,将通过FSNamesystem 的removePathAndBlocks 进行。
……(后续的方法和前面介绍的,都比较类似,都是一些过程性的东西,就不再讨论了)
更多精彩内容请关注:http://bbs.superwu.cn
关注超人学院微信二维码:
关注超人学院java免费学习交流群:
原文地址:http://crxy2013.blog.51cto.com/9922445/1656415