最近继续在看《Hadoop 2.X HDFS源码剖析》,现在看到了第三章NameNode部分。NameNode在hdfs这种文件系统中充当着master的角色,负责的功能有很多比如文件系统目录管理(命名空间管理)、数据块管理、数据节点管理、租约管理、缓存管理等等。这次主要写关于命名空间管理的笔记。
-
基本类型
hdfs中最基本的类应该就是INode了,无论是最后的目录、具体文件、软连接还是添加快照功能之后的引用都是这个类的子类,继承关系如下图所示
图表一
INode:包括parent这个字段表明父INode,还提供了isFile()、isDirectory()、isRoot()这些接口;
INodeWithAddtionalFields:包括id、name、permission、features这些字段,进一步拓展基本信息;
INodeFile:在父类的基础上定义了header以及bolcks(BlockInfo[]类型),对应的feature可以表示是否在构建中(underconstruction),是否有快照(snapshot);
INodeDirectory:在父类的基础上增加了childern字段,表明所有的子INode,对应的feature可以有是否有快照(snapshot),是否有限额(quota);
INodeReference:这个类以及子类主要是在开启快照功能的时候使用,在介绍之前首先介绍一下快照,所谓快照就是保存这个目录当前状态,这样不论以后对这个目录里面的文件做了删除、增加还是重命名,都可以通过快照获取这个时间下目录的所有文件;
就像下面的图表二所示
图表二
在t0时,存在文件/A/TXT,并且建立了对应时间/A目录的快照snapshot:t0,那么当t0之后将TXT移动到/B目录的时候,直接访问A是找不到文件的,但是可以通过访问/A这个INodeWithAdditionalFields对象的feature数组,访问到t0时刻的快照,接着就可以根据相应的INodeReference对象,找到TXT文件现在对应的位置。
这里WithName可以理解为文件修改之前的位置,DSTReference可以理解为文件修改之后的位置,他们都会指向一个WithCount,但是WithName跟前者可以使多对一的关系,因为可以存在多个保存了TXT这个文件的快照,而只能有一个DstReference表示这个文件当前的路径(WithCount的parent对象就是DstReference),最后WithCount指向了真正的文件/B/TXT。
-
关于日志
关于日志的细节很多,但是印象最深的地方只有如下两点(或许是我看的不够深入吧、[捂脸]):
1) 日志采用双缓冲的方式,同时进行逻辑以及物理IO:
这个缓冲区是由Ready(磁盘IO)以及Current(内存IO)两个部分组成的,写日志的线程,负责将日志写入Current中,而当Current写满了,需要保存到硬盘上的时候,将两块区域调换名字即可,这样日志持久化的操作不会影响当前日志的写入操作;
2) 由于可以存在多个写入日志的地方,调用写日志的时候使用一个保存所有输出流的集合journalSet进行调用,很方便:
journalSet对象有一个selectInputStreams的方法,用于选择需要输出的日志输出流,这样就把journalSet与需要输出的流绑定到一起了,接着直接调用journalSet.startLogSegment方法开始写入日志。
-
关于FSImage
这个类负责保存命名空间到磁盘、启动时加载fsImage文件以及加载editlog文件:
1) 保存命名空间:
保存的命名空间按照以下格式将内存中的内容,保存到磁盘中,如图表三所示
图表三
MagicNumber:魔数已经在很多技术中被采用了,相当于标识这个文件是哪种类型的文件,例如class文件的‘CAFEBABE’;
Sections:这是真正记录内存中数据的部分,例如INode信息、cache信息、快照信息等等;
FileSummary:这部分相当于sections的元数据,描述着每个section的长度以及起始位置;
FileSummaryLength:这部分描述FileSummary的长度。
启动的时候NameNode重后往前,先看FileSummaryLength,然后读取FileSummary,然后在根据各个section的元数据将Section加载到内存中,MagicNumber对应‘HDFSIMG1’。
2) 关于检查点
为了防止加载过大的editlog文件而导致的namenode启动太慢,向数据库里面一样,hdfs也有自己的检查点机制(当然没了数据库之中的回滚段什么的,所以还比较简单)。
在非HA的情况下,检查点操作都是由SecondaryNamenode进程操作的,然而在HA的情况下,都是由standbynamenode进行检查点操作,操作完成之后再传递给active namenode。
以上情况都是hadoop2.6.0中namenode的实现,版本不同具体实现也会不一样。相关截图已经打包上传。
2017.2.19
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/185706.html