本节讨论的都在hdfs工程中server.namenode包下
名字节点维护两个重要关系:
1. 文件系统的文件目录树,文件的数据块索引(文件与数据块的对应列表)
2. 数据块与数据节点(datanode)的对应关系
一 文件系统目录树
1. 主要的类
INode是hdfs对文件和目录的抽象,早期版本是保存了文件和目录的名称name这一属性的,在2.X版本中,没有这个属性了。INode中有parent(父目录)属性,设置和获取用户名,组名,权限的方法。还有一些判断是不是根目录之类的操作。
INodeDirectory通过继承INodeWithAdditionalFields间接继承了INode,抽象了HDFS的目录。里面保存了一组文件和其他一些目录,还有removeChild方法(删除目录中的文件或目录,当然如果是目录,他最终会遍历删除子项),对应的还有addChild。
同样的,INodeFile也通过INodeWithAdditionalFields继承了INode,他是关闭了的文件的一种抽象,包含了两个文件的属性:长整型的header,类型为BlockInfo的数据块集合。header保存了副本数和数据块的大小;BlockInfo继承自Block,里面保存了数据块和文件,数据块和数据节点的关系。
2. 物理信息
内存中的HDFS目录树和文件、目录元数据由INode和子类保存。只要节点宕机,这些就没了,所以命名空间镜像和编辑日志是保存在磁盘上的。空间镜像的实现类是FSImage,是内存元数据和磁盘元数据的桥梁。某一时刻,内存元数据导到磁盘上而后就通过将改动保存在日志中。
${dfs.namenode.name.dir}目录下有三个目录和一个文件,文件是in_use.lock(使用锁),current和image目录是hdfs是namenode格式化时产生的,在集群运行一段时间后会创建检查点previous.checkpoint目录。空间镜像和编辑日志保存在current目录下,0.13的版本是将镜像fsimage放在image目录下的,为了兼容性,所以image目录下也有镜像(同样的还有数据节点storage目录下也是为了兼容,知道就行了)。current目录下的4个文件分别是fsimage,edits,fstime,VERSION。
数据节点中,由DataStorage和FSDataset管理存储空间。名字节点是由FSImage和FSEditLog两个类完成的。FSImage负责空间镜像的保存和加载,与第二名字节点合作,执行检查点。以前,FSImage是继承Storage的,现在只是实现了Closeable。FSEditLog记录了对元数据的修改,因为不断产生日志,所以他依赖于输出流。
关于输出
FSImage有个saveFSImage方法,首先输出镜像文件的文件头,包括命名空间镜像格式的版本号、存储系统标识、节点数、数据块版本。然后使用saveINode2Image输出根节点,使用saveImage保存目录树的其他节点。
编辑日志被抽象成了只允许添加数据的输出流。EditLogOutputStream抽象了日志输出流,它的一个子类EditLogFileOutputStream用于将日志写往磁盘文件。
关于输入
FSImage.loadFSImage()读取命名空间镜像,并将它更新到内存元数据中。FSEditLog.loadFSEdits()则加载编辑日志,重放并应用日志记录的操作。
二数据块和数据节点管理
明天再写吧,也不知道继续研究源码会不会是个对的决策。