namenode加载fsimge好edits

上篇说到了namenode启动过程中主要是加载fsimge,edits和接收datanode的block信息。这篇主要分析namenode加载fsimage和edits的整个过程。

首先,了解一下fsimage和edits是存放什么信息的。

在hdfs-default.xml中通过dfs.name.dir和dfs.name.edits.dir配置fsimage和edits的存放路径,默认的话是存放在一个路径下的。

FSImage类继承了Storage类,来看看Storage类的描述:

 * Local storage information is stored in a separate file VERSION.
 * It contains type of the node, 
 * the storage layout version, the namespace id, and 
 * the fs state creation time.

 可以看到,存储信息是放在一个单独的VERSION文件中,包含了节点类型,layoutversion,namespaceId和fs创建时间,那么看看集群实际上是不是这样的:

#Mon Nov 11 15:54:28 CST 2013
namespaceID=620542034
cTime=0
storageType=NAME_NODE
layoutVersion=-32

 除了VERSION外,Storage还会产生一个in_use.lock的文件,表示当前集群我已经在使用了,你们要想在启动使用是不可以的。

同样DataStorage(datanode上存放block的,配置文件项为dfs.data.dir) 也继承Storage,在datanode的dfs.data.dir目录下你也能看到这2个文件。

继续Fsimage,在下面有5个文件:

enum NameNodeFile {
    IMAGE     ("fsimage"),
    TIME      ("fstime"),
    EDITS     ("edits"),
    IMAGE_NEW ("fsimage.ckpt"),
    EDITS_NEW ("edits.new");
    
    private String fileName = null;
    private NameNodeFile(String name) {this.fileName = name;}
    String getName() {return fileName;}
  }

 看看fsimage中的保存代码:

void saveFSImage(File newFile) throws IOException {
    FSNamesystem fsNamesys = FSNamesystem.getFSNamesystem();
    FSDirectory fsDir = fsNamesys.dir;
    long startTime = FSNamesystem.now();
    //
    // Write out data
    // 输出流写到fsimage文件中
    DataOutputStream out = new DataOutputStream(
                                                new BufferedOutputStream(
                                                                         new FileOutputStream(newFile)));
    try {
      out.writeInt(FSConstants.LAYOUT_VERSION);
      out.writeInt(namespaceID);
      out.writeLong(fsDir.rootDir.numItemsInTree());
      out.writeLong(fsNamesys.getGenerationStamp());
      byte[] byteStore = new byte[4*FSConstants.MAX_PATH_LENGTH];
      ByteBuffer strbuf = ByteBuffer.wrap(byteStore);
      // 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);
      strbuf = null;
    } finally {
      out.close();
    }

    LOG.info("Image file of size " + newFile.length() + " saved in " 
        + (FSNamesystem.now() - startTime)/1000 + " seconds.");
  }

 这里面除了一些基本信息外,最主要的就是inode的信息,就是存放文件和目录的基本信息,如时间,名称,使用者等。

关于inode更具体的信息,可以参看 http://blog.csdn.net/internetman/article/details/3850186

关于fsimage中的更详细格式,请参看  http://twtbgn.iteye.com/blog/1975256

在加载fsimage的过程中,会将fsimage和edits文件读入内存中进行合并,然后再写入到fsimage中去。在集群启动后,这件事就交给了secondarynamenode去做了。

 

你可能感兴趣的:(NameNode)