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操作。
声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。