花花世界蕾 发表于 2016-12-9 10:12:38

Hadoop学习二十五:Hadoop-Hdfs FSImage源码

一. FSImage作用


[*]加载硬盘镜像文件fsimage到内存。
[*]加载硬盘日志文件edits到内存。这个本来是类FSEditlog的事情,但是是由FSImage负责调用。
[*]保存内存中文件层次结构到硬盘文件fsimage中。
[*]保存内存中操作日志到硬盘文件edits上。按照对应关系,觉得是应该有这么一步吧。但遗憾的告诉你,这一步在整个文件系统中不存在。也就是FSImage可以分为内存和硬盘的,而edits只存在硬盘上,每次操作直接写入edits文件中。
[*]因为FSImage继承Storage,所以FSImage和DataStorage(http://zy19982004.iyunv.com/blog/1878758)一样,会做状态分析-----恢复操作-----状态转换操作。不同的是FSImage的状态转换支持IMPORT启动,对应着doImportCheckpoint()方法。
[*]其它作用。

二. FSImage成员变量


[*] FSEditLog editLog
[*]Collection<File> checkpointDirs:FSDirectory初始化时会从配置文件里读取"fs.checkpoint.dir",给其赋值。
[*]Collection<File> checkpointEditsDirs:FSDirectory初始化时会从配置文件里读取"fs.checkpoint.edits.dir",给其赋值。

三. FSImage方法


[*]boolean recoverTransitionRead(Collection<File> dataDirs,Collection<File> editsDirs,StartupOption startOpt) :完成状态分析-----恢复操作-----状态转换操作后调用boolean loadFSImage(MetaRecoveryContext recovery)。
[*]doImportCheckpoint():Load image from a checkpoint directory and save it into the current one.FSImage需要支持参数-importCheckpoint,该参数用于在某一个checkpoint目录里加载HDFS的目录信息,并更新到当前系统。
[*]boolean loadFSImage(MetaRecoveryContext recovery):在所有的Storage中,读取最新的NameNode持久化信息,并应用相应的日志,当loadFSImage()调用返回以后,内存中的目录树就是最新的。loadFSImage()会返回一个标记,如果Storage中有任何和内存中最终目录树中不一致的Image(最常见的情况是日志文件不为空,那么,内存中的fsimage应该是Storage的fsimage加上日志,当然还有其它情况),那么,该标记为true。
//dirIterator find 最新的NameNode持久化信息StorageDirectory latestNameSD and latestEditsSD
needToSave |= loadFSImage(getImageFile(latestNameSD, NameNodeFile.IMAGE));
needToSave |= (loadFSEdits(latestEditsSD, recovery) > 0);

 
[*]  boolean loadFSImage(File curFile):从硬盘上加载fsimage文件,应用到内存中。
//1.循环从FSImage文件输入流in中读取如下基本信息,构建成一个INodeDirectory(INodeDirectory包含INodeFile,INodeFile包含哪些Block等);然后把此INodeDirectory加入FSDirectory中
for-each{parentINode = fsDir.addToParent(path, parentINode, permissions,
blocks, replication, modificationTime,
atime, nsQuota, dsQuota, blockSize);
}
//2.加载Datanode信息
this.loadDatanodes(imgVersion, in);
//3.load Files Under Construction
this.loadFilesUnderConstruction(imgVersion, in, fsNamesys);
//4
this.loadSecretManagerState(imgVersion, in, fsNamesys);

 
[*] int loadFSEdits(StorageDirectory sd, MetaRecoveryContext recovery):加载edits文件到内存中;如果存在edit.new文件,加载此文件到内存。返回一个load了多少个edits文件。
int loadFSEdits(StorageDirectory sd, MetaRecoveryContext recovery)
throws IOException {
numEdits = FSEditLog.loadFSEdits(edits, recovery);
if (editsNew.exists() && editsNew.length() > 0) {
numEdits += FSEditLog.loadFSEdits(edits, recovery);
}
return numEdits;
}
 
[*]void saveFSImage(File newFile):保存内存中的文件层次结构到fsimage文件中。和4过程相反。
// save the root
saveINode2Image(strbuf, fsDir.rootDir, out);
// save the rest of the nodes
saveImage(strbuf, 0, fsDir.rootDir, out);
fsNamesys.saveFilesUnderConstruction(out);
fsNamesys.saveSecretManagerState(out);
 
[*]void rollFSImage():把所有的edits.new都改为edits(调用editLog.purgeEditLog()),然后再把fsimage.ckpt改为fsimage。对应着http://zy19982004.iyunv.com/admin/blogs/1870624三.6
四. FSImage类图

五. FSImage其它知识点
  参考http://caibinbupt.iyunv.com/blog/289759
页: [1]
查看完整版本: Hadoop学习二十五:Hadoop-Hdfs FSImage源码