Hadoop-2.4.1学习之创建fsimage和edits源码分析
来源:互联网 发布:beyong compare mac 编辑:程序博客网 时间:2024/06/06 08:26
在Hadoop中fsimage保存最新的检查点信息,edits保存自最新检查点后的命名空间的变化。在分析hdfs namenode–format的源代码时,已经明确了该过程根据配置文件的信息创建fsimage和edits文件,这篇文章具体分析一下创建fsimage和edits文件的源代码。在NameNode的format方法中,有如下的代码:
FSImage fsImage = new FSImage(conf, nameDirsToFormat, editDirsToFormat); try { FSNamesystem fsn = new FSNamesystem(conf, fsImage); fsImage.getEditLog().initJournalsForWrite(); if (!fsImage.confirmFormat(force, isInteractive)) { return true; // aborted } fsImage.format(fsn, clusterId); } catch (IOException ioe) { LOG.warn("Encountered exception during format: ", ioe); fsImage.close(); throw ioe; }
在这段代码中主要涉及到了三个类,分别为FSImage、FSNamesystem和FSEditLog,其中FSImage负责检查点,FSEditLog维护命名空间变动的日志,FSNamesystem为DataNode执行实际的簿记工作。创建fsImage对象的源代码为
/** * Construct the FSImage. Set the default checkpoint directories. * * Setup storage and initialize the edit log. * * @param conf Configuration * @param imageDirs Directories the image can be stored in. * @param editsDirs Directories the editlog can be stored in. * @throws IOException if directories are invalid. */ protected FSImage(Configuration conf,Collection<URI> imageDirs, List<URI> editsDirs)throws IOException {this.conf = conf;/* NNStorage负责管理NameNode使用的StorageDirectories*/storage = new NNStorage(conf, imageDirs, editsDirs);/*根据dfs.namenode.name.dir.restore的值决定是否尝试重新存储失败的存储目录* 默认值为false*/ if(conf.getBoolean(DFSConfigKeys.DFS_NAMENODE_NAME_DIR_RESTORE_KEY, DFSConfigKeys.DFS_NAMENODE_NAME_DIR_RESTORE_DEFAULT)) { storage.setRestoreFailedStorage(true); }this.editLog = new FSEditLog (conf, storage, editsDirs);/*NNStorageRetentionManager负责检查NameNode的存储目录, *并在fsimage和edits文件上执行保留策略。*/ archivalManager = new NNStorageRetentionManager(conf, storage, editLog); }
FSImage的构造方法中,创建了NNStorage、FSEditLog和NNStorageRetentionManager对象,NNStorage的构造方法源代码如下:
public NNStorage(Configuration conf, Collection<URI> imageDirs, Collection<URI> editsDirs) throws IOException { super(NodeType.NAME_NODE); storageDirs = new CopyOnWriteArrayList<StorageDirectory>(); // this may modify the editsDirs, so copy before passing in setStorageDirectories(imageDirs, Lists.newArrayList(editsDirs), FSNamesystem.getSharedEditsDirs(conf)); }
NNStorage中的setStorageDirectories方法用于初始化存储fsimage和edits文件的目录。这里不分析该方法的全部源代码,主要分析初始化fsimage的部分,如下:
// 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("file") == 0) { this.addStorageDir(new StorageDirectory(new File(dirName.getPath()), dirType, sharedEditsDirs.contains(dirName))); // Don't lock the dir if it's shared. } }
在该段代码中fsNameDirs和fsEditsDirs分别为参数dfs.namenode.name.dir和dfs.namenode.edits.dir设置的目录,默认情况下二者指向相同的目录。如果二者的值相同那么fsimage的类型就为NameNodeDirType.IMAGE_AND_EDITS,否则为NameNodeDirType.IMAGE。需要注意的是,到目前为止虽然根据配置文件创建了表示相应目录的File对象,但还没有在本地文件系统上创建实际的目录。现在回到FSIamge的构造方法中,在创建了NNStorage对象后,接下来创建FSEditLog对象,该类的构造方法为:
/** * Constructor for FSEditLog. Underlying journals are constructed, but * no streams are opened until open() is called. * * @param conf The namenode configuration * @param storage Storage object used by namenode * @param editsDirs List of journals to use */ FSEditLog(Configuration conf, NNStorage storage, List<URI> editsDirs) { isSyncRunning = false; this.conf = conf;this.storage = storage;//在format阶段,metrics的值为null metrics = NameNode.getNameNodeMetrics(); lastPrintTime = now(); // If this list is empty, an error will be thrown on first use // of the editlog, as no journals will exist this.editsDirs = Lists.newArrayList(editsDirs); this.sharedEditsDirs = FSNamesystem.getSharedEditsDirs(conf); }
在创建完了FSEditLog和NNStorageRetentionManager对象后,FSIamge的构造方法执行完毕,回到NameNode的format方法中。接下来就是要根据FSImage对象创建FSNamesystem,前面曾提到FSNamesystem为DataNode执行实际的簿记工作,实际执行的该类的构造方法如下,其中ignoreRetryCache的值为false:
/** * Create an FSNamesystem associated with the specified image. * * Note that this does not load any data off of disk -- if you would * like that behavior, use {@link #loadFromDisk(Configuration)} * * @param conf configuration * @param fsImage The FSImage to associate with * @param ignoreRetryCache Whether or not should ignore the retry cache setup * step. For Secondary NN this should be set to true. * @throws IOException on bad configuration */ FSNamesystem(Configuration conf, FSImage fsImage, boolean ignoreRetryCache) throws IOException
由于该构造方法代码比较多,就不贴出来了。可以概括为在该构造方法中,实例化了诸如BlockManager、DatanodeStatistics、FSDirectory、CacheManager等对象,读取了配置文件中的一些信息(后面计划专门研究该类)。在创建完毕FSNamesystem对象后,执行的是FSEditLog的initJournalsForWrite()方法,该方法的代码如下:
private State state = State.UNINITIALIZED;public synchronized void initJournalsForWrite() { Preconditions.checkState(state == State.UNINITIALIZED || state == State.CLOSED, "Unexpected state: %s", state); initJournals(this.editsDirs); state = State.BETWEEN_LOG_SEGMENTS; }
在该方法中先检查日志的状态,FSEditLog刚创建时的状态为UNINITIALIZED,执行完initJournals()方法后日志的状态为BETWEEN_LOG_SEGMENTS,意味日志还未打开。日志的初始化具体由initJournals()完成,该方法的代码如下:
private synchronized void initJournals(List<URI> dirs) { int minimumRedundantJournals = conf.getInt( DFSConfigKeys.DFS_NAMENODE_EDITS_DIR_MINIMUM_KEY, DFSConfigKeys.DFS_NAMENODE_EDITS_DIR_MINIMUM_DEFAULT);//管理日志集合的对象 journalSet = new JournalSet(minimumRedundantJournals); for (URI u : dirs) { boolean required = FSNamesystem.getRequiredNamespaceEditsDirs(conf) .contains(u); if (u.getScheme().equals(NNStorage.LOCAL_URI_SCHEME)) { StorageDirectory sd = storage.getStorageDirectory(u); if (sd != null) { journalSet.add(new FileJournalManager(conf, sd, storage), required, sharedEditsDirs.contains(u)); } } else { journalSet.add(createJournal(u), required, sharedEditsDirs.contains(u)); } } if (journalSet.isEmpty()) { LOG.error("No edits directories configured!"); } }
该方法根据传递的目录集合创建FileJournalManager对象,并添加到JournalSet对象中,其中一个FileJournalManager对象管理一个保存edits文件的目录。初始化edits文件后,接下来就是对fsimage进行格式化了,具体代码为:
void format(FSNamesystem fsn, String clusterId) throws IOException { long fileCount = fsn.getTotalFiles(); // Expect 1 file, which is the root inode Preconditions.checkState(fileCount == 1, "FSImage.format should be called with an uninitialized namesystem, has " + fileCount + " files"); NamespaceInfo ns = NNStorage.newNamespaceInfo(); LOG.info("Allocated new BlockPoolId: " + ns.getBlockPoolID()); ns.clusterID = clusterId; storage.format(ns); editLog.formatNonFileJournals(ns); saveFSImageInAllDirs(fsn, 0); }
在该代码中实际执行创建fsimage文件的代码为最后一行的saveFSImageInAllDirs(fsn,0),该方法将实际的工作委托给下面的方法:
saveFSImageInAllDirs(source, NameNodeFile.IMAGE, txid, null);
在该方法中会根据保存fsimage的目录的个数创建与之相等的线程,这些线程完成实际的创建fsimage的任务。最后会清理旧的edits和检查点文件。
通过上面的分析可以发现,在执行hdfs namenode –format时仅创建了fsimage文件,并没有创建edits文件,但已经创建了相关对象。这一点也可以在执行完format后在本地文件系统中确认,目录中只有fsimage文件。
- Hadoop-2.4.1学习之创建fsimage和edits源码分析
- Hadoop-2.4.1学习之edits和fsimage查看器
- 【源码】Hadoop 2.x中fsimage和edits合并实现
- 第124讲:Hadoop集群管理之fsimage和edits工作机制内幕详解学习笔记
- hadoop中fsimage和edits的区别
- Hadoop中fsimage和edits合并问题
- hadoop的元数据fsimage和edits
- hadoop之fsimage和edits工作机制和元数据namenode宕机恢复
- Hadoop中的fsimage和edits(能力工场--Hadoop)
- Hadoop学习;测试;启动bug;secondary合并edits到fsimage
- Hadoop NameNode启动之FSImage、edits重置(三)
- Hadoop中的fsimage和edits log编辑日志
- Hadoop中的fsimage和edits log编辑日志
- Hadoop 2.x中fsimage和edits合并实现
- Hadoop 2.x中fsimage和edits合并实现
- Hadoop 2.x中fsimage和edits合并实现
- Hadoop文件系统元数据fsimage和编辑日志edits
- Hadoop 1.x中fsimage和edits合并实现
- java字符串占位符
- android内存泄露 out of memory Bitmap内存溢出
- myeclipse配置本地的struts-2.0.dtd
- 异常处理,简单而又复杂的问题
- Java NIO SocketChannel客户端例子(支持连接失败后自动重连)
- Hadoop-2.4.1学习之创建fsimage和edits源码分析
- jquery-datatable基本配置
- C++学习笔记(第七章 自定义数据类型 结构体应用 之三)
- python利用subprocess实现多进程
- 关于message-resources 配置中parameter的值
- 张新民-O2O时代的Wi-Fi新应用
- tar 命令常见参数列表
- 第十六章 16.5节练习
- 网页错误代码图解 404、403之类意思