/ 中存储网

HDFS元数据解析

2013-06-07 00:00:00 来源:中存储
1、元数据(Metadata):维护HDFS文件系统中文件和目录的信息,分为内存元数据和元数据文件两种。NameNode维护整个元数据。 HDFS实现时,没有采用定期导出元数据的方法,而是采用元数据镜像文件(FSImage)+日子文件(edits)的备份机制。 2、Block:文件内容而言。 寻路径流程:           路径信息                         bocks[]                                   triplets[]           Client ------------》INode---------------------》BlockInfo --------------------------》DataNode。   INode:文件的基本元素:文件和目录 BlockInfo: 文件内容对象 DatanodeDescriptor:具体存储对象。 3 、 FSImage和edits的checkPoint。FSImage有2个状态,分别是FsImage和FsImage.ckpt,后者表示正在checkpoint的过程中,上传后将会修改为FSImage文件,同理edits也有两个状态,edits和edits.new。 4、NameNode format情景分析: 遍历元数据存储目录,提示用户是否格式化?(NameNode.java里format函数)
private static boolean format( Configuration conf ,
                                boolean isConfirmationNeeded )
      throws IOException {
    Collection<URI > dirsToFormat = FSNamesystem. getNamespaceDirs(conf );
    Collection<URI > editDirsToFormat =
                 FSNamesystem .getNamespaceEditsDirs (conf );
    for( Iterator< URI> it = dirsToFormat.iterator (); it. hasNext() ;) {
      File curDir = new File (it .next (). getPath()) ;
      if (! curDir. exists())
        continue;
      if (isConfirmationNeeded ) {
        System .err .print ("Re-format filesystem in " + curDir + " ? (Y or N) ");
        if (! (System .in .read () == 'Y')) {
          System .err .println ("Format aborted in " + curDir );
          return true ;
        }
        while(System .in .read () != 'n') ; // discard the enter-key
      }
    }

    FSNamesystem nsys = new FSNamesystem (new FSImage(dirsToFormat ,
                                         editDirsToFormat ), conf) ;
    nsys.dir.fsImage .format ();
    return false;
  }
创建元数据内存镜像,包括类FSNamesystem实例化对象,类FSDirectory实例化对象,类FSImage对象,类Edits对象。创建FsNameSystem对象主要完成:BlockManager,FSDirectory对象以及初始化成员变量。FSImage对象主要完成对layoutVersion、namespaceID,CTime赋值为0,实例化FSEditLog。在类FSDirectory,创建了HDFS根目录节点rootDir。
FSNamesystem( FSImage fsImage, Configuration conf ) throws IOException {
    this. blockManager = new BlockManager (this, conf) ;
    setConfigurationParameters (conf );
    this. dir = new FSDirectory(fsImage , this, conf );
    dtSecretManager = createDelegationTokenSecretManager (conf );
  }

  FSImage( Collection< URI> fsDirs , Collection< URI> fsEditsDirs )
      throws IOException {
    this() ;
    setStorageDirectories( fsDirs, fsEditsDirs );
  }

 void setStorageDirectories(Collection <URI > fsNameDirs,
                             Collection< URI> fsEditsDirs ) throws IOException {
    this. storageDirs = new ArrayList <StorageDirectory >() ;
    this. removedStorageDirs = new ArrayList <StorageDirectory >() ;
   
   // Add all name dirs with appropriate NameNodeDirType
    for (URI dirName : fsNameDirs ) {
      checkSchemeConsistency (dirName );
      boolean isAlsoEdits = false;
      for (URI editsDirName : fsEditsDirs) {
        if (editsDirName .compareTo (dirName ) == 0) {
          isAlsoEdits = true;
          fsEditsDirs .remove (editsDirName );
          break;
        }
      }
      NameNodeDirType dirType = (isAlsoEdits ) ?
                          NameNodeDirType .IMAGE_AND_EDITS :
                          NameNodeDirType .IMAGE ;
      // Add to the list of storage directories, only if the
      // URI is of type file://
      if(dirName .getScheme (). compareTo( JournalType.FILE .name (). toLowerCase())
          == 0){
        this.addStorageDir (new StorageDirectory(new File(dirName. getPath()) ,
            dirType ));
      }
    }
   
    // Add edits dirs if they are different from name dirs
    for (URI dirName : fsEditsDirs ) {
      checkSchemeConsistency (dirName );
      // Add to the list of storage directories, only if the
      // URI is of type file://
      if(dirName .getScheme (). compareTo( JournalType.FILE .name (). toLowerCase())
          == 0)
        this.addStorageDir (new StorageDirectory(new File(dirName. getPath()) ,
                    NameNodeDirType .EDITS ));
    }
  }
对内存镜像数据中的数据结构进行初始化:主要有FSImage的format函数完成,layoutVersion:软件所处的版本。namespaceID:在Format时候产生,当data node注册到Name Node后,会获得该NameNode的NameSpaceID,并作为后续与NameNode通讯的身份标识。对于未知身份的Data Node,NameNode拒绝通信。CTime:表示FSimage产生的时间。checkpointTime:表示NameSpace第一次checkpoint的时间。 
 public void format () throws IOException {
    this. layoutVersion = FSConstants .LAYOUT_VERSION ;
    this. namespaceID = newNamespaceID ();
    this. cTime = 0L ;
    this. checkpointTime = FSNamesystem .now ();
    for (Iterator <StorageDirectory > it =
                           dirIterator (); it. hasNext() ;) {
      StorageDirectory sd = it .next ();
      format (sd );
    }
  }
对内存镜像写入元数据备份目录。FSImage的format方法会遍历所有的目录进行备份。如果是FSImage的文件目录,则调用saveFSImage保存FSImage,如果是Edits,则调用editLog.createEditLogFile,最后调用sd.write方法创建fstime和VERSION文件。VERSION文件通常最后写入。
void format(StorageDirectory sd ) throws IOException {
    sd.clearDirectory (); // create currrent dir
    sd.lock ();
    try {
      saveCurrent (sd );
    } finally {
      sd .unlock ();
    }
    LOG.info ("Storage directory " + sd. getRoot()
             + " has been successfully formatted.");
  }
最后分析一下元数据应用的场景: 1、格式化时。 2、Hadoop启动时。 3、元数据更新操作时。 4、如果NameNode与Secondary NameNode、Backup Node或checkpoint Node配合使用时,会进行checkPoint操作。