一. FSImage作用

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

二. FSImage成员变量

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

三. FSImage方法

  1. boolean recoverTransitionRead(Collection<File> dataDirs,Collection<File> editsDirs,StartupOption startOpt) :完成状态分析-----恢复操作-----状态转换操作后调用boolean loadFSImage(MetaRecoveryContext recovery)。
  2. doImportCheckpoint():Load image from a checkpoint directory and save it into the current one.FSImage需要支持参数-importCheckpoint,该参数用于在某一个checkpoint目录里加载HDFS的目录信息,并更新到当前系统。
  3. 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);
//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)
      throws IOException {
    numEdits = FSEditLog.loadFSEdits(edits, recovery);
    if (editsNew.exists() && editsNew.length() > 0) {
      numEdits += FSEditLog.loadFSEdits(edits, recovery);
    }

    return numEdits;
  }
  1. 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);
  1. void rollFSImage():把所有的edits.new都改为edits(调用editLog.purgeEditLog()),然后再把fsimage.ckpt改为fsimage

 

 

四. FSImage类图

 

hadoop表分区数 hadoop fsimage_Storage

 

 

五. FSImage其它知识点

      参考http://caibinbupt.iteye.com/blog/289759