在HDFS中,由FSNamesystem来表示总的元数据,它有三个重要的成员变量,分别是FSDirectory dir, BlocksMap blocksMap和NavigableMap<String,DatanodeDescriptor> datanodeMap。
FSDirectory存储整个文件系统的目录状态,对整个目录结构的管理通过调用FSImage和FSEditLog的方法从namenode本地磁盘读取元数据信息和向本地磁盘写入元数据信息,并登记对目录结构所作的修改到日志文件。另外,FSDirectory保存了文件名和数据块的映射关系。FsDirectory 实现了INode的管理,通过INode我们就可以知道文件的名称、创建时间、大小等属性。INodeFile中设置了BlockInfo blocks[] 来保存该文件所对应的所有Block信息,并且该类提供了操作Block的方法。
BlocksMap负责维护了三种信息:block->datanode list 、block->INodeFile、datanode->blocks。block->datanode的信息没有持久化存储,而是namenode通过datanode的blockreport获取block->blockList的列表。BlockInfo中有两个重要的成员变量,一是InodeFile inode,而InodeFile中又包含了BlockInfo[] blocks。这就方便多了,通过Block我们可以获取对应的INode,通过INode我们可以获取该文件的所有blocks。二是Object[] triplets,该对象保存了三个块,分别是当前块,该块的前一个块以及该块的下一个块。通过该对象我们可以遍历该block所在datanode的所有blocks。
datanodeMap完成了对HDFS所有的DataNode的管理,通过key(StorageId)可以快速定位相应的DataNode。StorageID是DataNode被注册到NameNode时,DataNode持久化保存其唯一的存储ID(storage ID)。存储ID是一个DataNode的内部标识符,该标识符能够确保即使是服务器用不同的IP地址或者端口启动,仍然可以被识别。存储ID在DataNode首次注册到NameNode时即被分配,一旦分配后便无法更改。DatanodeDescriptor主要保存block与对应的DatanodeDiscriptor的关联关系。