FSImage

类FSImage如下图:

  

FSImage - Bell - Bell

 

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

 

FSImage - Bell - Bell

 

 

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

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

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

 

FSImage - Bell - Bell

 

FSImage - Bell - Bell

 

 

最开始是版本号(注意,各版本文件布局不一样,文中分析的样本是0.17的),然后是命名空间的ID号,文件个数和最高文件版本号(就是说,下一次产生文件版本号的初始值)。接下来就是文件的信息啦,首先是文件名,然后是该文件的副本数,接下来是修改时间/访问时间,数据块大小,数据块数目。数据块数目如果大于0,表明这是个文件,那么接下来就是numBlocks个数据块(浅蓝),如果数据块数目等于0,那该条目是目录,接下来是应用于该目录的quota。最后是访问控制的一些信息。文件信息一共有numFiles个,接下来是处于构造状态的文件的信息。(有些版本可能还会保留DataNode的信息,但0.17已经不保存这样的信息啦)。loadFSImage(File curFile)的对应方法是saveFSImage(File newFile),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。如下图:

 

FSImage - Bell - Bell

 

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

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

 

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

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值