首页 百科知识 源代码分析(二零)

源代码分析(二零)

时间:2023-09-22 百科知识 版权反馈
【摘要】:分析FSImage,不免要跟DataStorage去做比较。前面我们已经分析过DataStorage的状态变化,包括升级/回滚/提交,FSImage也有类似的升级/回滚/提交动作,而且这部分的行为和DataStorage是比较一致,如下状态转移图。FSImage需要支持参数-importCheckpoint,该参数用于在某一个checkpoint目录里加载HDFS的目录信息,并更新到当前系统,该参数的主要功能在方法doImportCheckpoint中。GetImageServlet是和从NameNode进行文件通信的接口,这个场景留到我们分析从NameNode时再进行分析。

前面我们提过关系:文件名à数据块持久化在磁盘上,所有对目录树的更新和文件名à数据块关系的修改,都必须能够持久化。为了保证每次修改不需要从新保存整个结构,HDFS使用操作日志,保存更新。

现在我们可以得到NameNode需要存储在Disk上的信息了,包括:

[hadoop@localhostdfs]$ ls -R name
name:
current  image  in_use.lock

name/current:
edits  fsimage  fstime VERSION

name/image:
fsimage

in_use.lock的功能和DataNode的一致。fsimage保存的是文件系统的目录树,edits则是文件树上的操作日志,fstime是上一次新打开一个操作日志的时间(long型)。

image/fsimage是一个保护文件,防止0.13以前的版本启动(0.13以前版本将fsimage存放在name/image目录下,如果用0.13版本启动,显然在读fsimage会出错J)。

我们可以开始讨论FSImage了,类FSImage如下图:

mhtml:file://I:\技术文章下载\2010-4-23整理到notebook\Hadoop汇总2010-4-22\Hadoop源码分析\Hadoop源代码分析(二零)%20-%20-%20JavaEye技术网站.mht!http://caibinbupt.javaeye.com/upload/attachment/59166/ae1d7aa8-d5ab-3cd9-8232-e385ab54f48a.jpg 

 

分析FSImage,不免要跟DataStorage去做比较(上图也保留了类DataStorage)。前面我们已经分析过DataStorage的状态变化,包括升级/回滚/提交,FSImage也有类似的升级/回滚/提交动作,而且这部分的行为和DataStorage是比较一致,如下状态转移图。图中update方法和DataStorage的差别比较大,是因为处理数据库和处理文件系统名字空间不一样,其他的地方都比较一致。FSImage也能够管理多个Storage,而且还能够区分Storage为IMAGE(目录结构)/EDITS(日志)/IMAGE_AND_EDITS(前面两种的组合)。

mhtml:file://I:\技术文章下载\2010-4-23整理到notebook\Hadoop汇总2010-4-22\Hadoop源码分析\Hadoop源代码分析(二零)%20-%20-%20JavaEye技术网站.mht!http://caibinbupt.javaeye.com/upload/attachment/58166/e7e00462-246c-353d-aa8a-68caf44699af.jpg

 

 

我们可以看到,FSImage和DataStorage都有recoverTransitionRead方法。FSImage的recoverTransitionRead方法主要步骤是检查系统一致性(analyzeStorage)并尝试恢复,初始化新的storage,然后根据启动NameNode的参数,做升级/回滚等操作。

FSImage需要支持参数-importCheckpoint,该参数用于在某一个checkpoint目录里加载HDFS的目录信息,并更新到当前系统,该参数的主要功能在方法doImportCheckpoint中。该方法很简单,通过读取配置的checkpoint目录来加载fsimage文件和日志文件,然后利用saveFSImage(下面讨论)保存到当前的工作目录,完成导入。

loadFSImage(File curFile)用于在fsimage中读入NameNode持久化的信息,是FSImage中最重要的方法之一,该文件的结构如下:

mhtml:file://I:\技术文章下载\2010-4-23整理到notebook\Hadoop汇总2010-4-22\Hadoop源码分析\Hadoop源代码分析(二零)%20-%20-%20JavaEye技术网站.mht!http://caibinbupt.javaeye.com/upload/attachment/58168/4fd76e70-e858-3fbd-930b-54ce17bf8f17.jpg

 

 

最开始是版本号(注意,各版本文件布局不一样,文中分析的样本是0.17的),然后是命名空间的ID号,文件个数和最高文件版本号(就是说,下一次产生文件版本号的初始值)。接下来就是文件的信息啦,首先是文件名,然后是该文件的副本数,接下来是修改时间/访问时间,数据块大小,数据块数目。数据块数目如果大于0,表明这是个文件,那么接下来就是numBlocks个数据块(浅蓝),如果数据块数目等于0,那该条目是目录,接下来是应用于该目录的quota。最后是访问控制的一些信息。文件信息一共有numFiles个,接下来是处于构造状态的文件的信息。(有些版本可能还会保留DataNode的信息,但0.17已经不保存这样的信息啦)。loadFSImage(File curFile)的对应方法是saveFSImage(FilenewFile),FSImage中还有一系列的方法(大概7,8个)用于配合这两个方法工作,我们就不再深入讨论了。

loadFSEdits(StorageDirectory sd)用于加载日志文件,并把日志文件记录的内容应用到NameNode,loadFSEdits只是简单地调用FSEditLog中对应的方法。

loadFSImage()和saveFSImage()是另外一对重要的方法。

loadFSImage()会在所有的Storage中,读取最新的NameNode持久化信息,并应用相应的日志,当loadFSImage()调用返回以后,内存中的目录树就是最新的。loadFSImage()会返回一个标记,如果Storage中有任何和内存中最终目录树中不一致的Image(最常见的情况是日志文件不为空,那么,内存中的Image应该是Storage的Image加上日志,当然还有其它情况),那么,该标记为true。

saveFSImage()的功能正好相反,它将内存中的目录树持久化,很自然,目录树持久化后就可以把日志清空。saveFSImage()会创建edits.new,并把当前内存中的目录树持久化到fsimage.ckpt(fsimage现在还存在),然后重新打开日志文件edits和edits.new,这会导致日志文件edits和edits.new被清空。最后,saveFSImage()调用rollFSImage()方法。

rollFSImage()上来就把所有的edits.new都改为edits(经过了方法saveFSImage,它们都已经为空),然后再把fsimage.ckpt改为fsimage。如下图:

mhtml:file://I:\技术文章下载\2010-4-23整理到notebook\Hadoop汇总2010-4-22\Hadoop源码分析\Hadoop源代码分析(二零)%20-%20-%20JavaEye技术网站.mht!http://caibinbupt.javaeye.com/upload/attachment/58164/9c2099a5-b0c4-37b1-b0cf-27a0449448ce.jpg

 

为了防止误调用rollFSImage(),系统引入了状态CheckpointStates.UPLOAD_DONE。

有了上面的状态转移图,我们就很好理解方法recoverInterruptedCheckpoint了。

 

图中存在另一条路径,应用于GetImageServlet中。GetImageServlet是和从NameNode进行文件通信的接口,这个场景留到我们分析从NameNode时再进行分析。

 

最后我们分析一下和检查点相关的一个类,rollFSImage()会返回这个类的一个实例。CheckpointSignature用于标识一个日志的检查点,它是StorageInfo的子类,同时实现了WritableComparable接口,出了StorageInfo的信息,它还包括了两个属性:editsTimecheckpointTimeeditsTime是日志的最后修改时间,checkpointTime是日志建立时间。在和从NameNode节点的通信中,需要用CheckpointSignature,来保证从NameNode获得的日志是最新的。


免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈