Hadoop源码学习笔记之NameNode启动场景流程三:FSNamesystem初始化源码剖析
上篇内容分析了http server的启动代码,这篇文章继续从initialize()方法中按执行顺序进行分析。内容还是分为三大块:
一、源码调用关系分析
二、伪代码执行流程
三、代码图解
一、源码调用关系分析
上一篇内容是NameNode启动http server的分析,是根据锁定NameNode的main()入口,发现了该入口仅有两行核心代码,先进入到了第一行核心代码
createNameNode()中,发现默认情况是new了一个NameNode对象。在NameNode的构造方法中,有一些很重要的初始化操作,比如启动
http server、加载元数据、初始化rpc server、安全模式检查等。
废话不多说,前面的NameNode.main()、createNameNode()、new NameNode()都不再赘述、直接从initialize()说起:
- protected void initialize(Configuration conf) throws IOException {
- // 可以通过找到下面变量名的映射,在hdfs-default.xml中找到对应的配置
- if (conf.get(HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS) == null) {
- String intervals = conf.get(DFS_METRICS_PERCENTILES_INTERVALS_KEY);
- if (intervals != null) {
- conf.set(HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS,
- intervals);
- }
- }
- ......
- // 核心代码:启动HttpServer
- if (NamenodeRole.NAMENODE == role) {
- startHttpServer(conf);
- }
- this.spanReceiverHost = SpanReceiverHost.getInstance(conf);
- // 核心代码:FSNamesystem初始化
- loadNamesystem(conf);
- // 核心代码:后面rpc server启动流程篇研究
- rpcServer = createRpcServer(conf);
- ......
- // 核心代码:启动一些服务组件,包括rpc server等
- startCommonServices(conf);
- }
本篇内容主要是关于管理磁盘元数据的FSNamesystem初始化流程,所以从方法名即可推测loadNamesystem()是需要我们重点关注的核心中的核心。
点进去:
- protected void loadNamesystem(Configuration conf) throws IOException {
- // 核心代码:从磁盘上加载元数据,loadFromDisk()就是从磁盘上读取fsimage和edits文件。
- this.namesystem = FSNamesystem.loadFromDisk(conf);
- }
我们都知道NameNode的功能之一是,在NameNode启动的时候,会将磁盘上的fsimage和edits两个文件都读取到内存中进行合并,形成一份最新的
元数据。这份最新的元数据放在哪呢?其实是放在了内存中由FSNamesystem进行管理。真的是这样的吗?我们继续往下看,进入到loadFromDisk():
- /**
- * Instantiates an FSNamesystem loaded from the image and edits
- * directories specified in the passed Configuration.
- *
- * @param conf the Configuration which specifies the storage directories
- * from which to load
- * @return an FSNamesystem which contains the loaded namespace
- * @throws IOException if loading fails
- */
- static FSNamesystem loadFromDisk(Configuration conf) throws IOException {
- checkConfiguration(conf);
- // 核心代码:构造一个FSImage对象,从NamespaceDirs、NamespaceEditsDirs指定的路径加载
- FSImage fsImage = new FSImage(conf,
- // 默认是从 DFS_NAMENODE_NAME_DIR_KEY 加载fsimage文件
- FSNamesystem.getNamespaceDirs(conf),
- // 默认是从 DFS_NAMENODE_EDITS_DIR_KEY 加载edits文件
- FSNamesystem.getNamespaceEditsDirs(conf));
- // 核心代码:根据指定了fsimage和edits文件路径的fsimage对象,实例化FSNamesystem对象
- FSNamesystem namesystem = new FSNamesystem(conf, fsImage, false);
- StartupOption startOpt = NameNode.getStartupOption(conf);
- if (startOpt == StartupOption.RECOVER) {
- namesystem.setSafeMode(SafeModeAction.SAFEMODE_ENTER);
- }
- ...try {
- // 核心代码:从磁盘上加载数据,在内存中合并数据
- // 在NameNode刚启动的时候,会从磁盘读取fsimage和edits文件到内存中,合并为一份最新的
- // 元数据,然后将这份新的元数据写出到磁盘替换之前旧的fsimage。然后,还会重新打开一个
- // 空的edits文件,以供接下来的元数据变动日志写入。这个loadFSImage()主要就是干了这么一件事情
- // 会在namenode元数据管理研究时进行深入详细剖析。
- namesystem.loadFSImage(startOpt);
- } catch (IOException ioe) {
- ...
- }
...- return namesystem;
- }
首先这个loadFromDisk()有一段注释,将这个方法的功能和目的说的也很明白了:根据配置文件指定的路径,实例化一个从image和edits加载元数据
的FSNamesystem对象。下面开始分析核心代码,这段有3行核心代码:
fsimage = new FSImage(conf, NameSpaceDirs, NameSpaceEditsDirs);
这行代码是构造了一个FSImage对象,从NameSpaceDirs, NameSpaceEditsDirs分别
读取fsimage和edits文件。其中NameSpaceDirs和NameSpaceEditsDirs经过溯源分别对应 dfs.namenode.name.dir 和
dfs.namenode.shared.edits.dir,这两个属性都可以在hdfs-default.xml中查看和配置。
FSNamesystem namesystem = new FSNamesystem(conf, fsimage, false);
根据上面指定了fsimage路径和edits路径的fsimage对象,构造一个FSNamesystem对象。
namesystem.loadFSImage();
开始执行loadFSImage()方法,从磁盘上加载数据并在内存中进行合并。
注意,在合并fsimage和edits形成一份新的元数据之后,会将这份新的元数据写出到磁盘替换旧的fsimage文件,然后还会打开一个新的edits
文件,以供接下来的元数据变动的日志写入。这些操作都是在loadFSImage()中完成的,具体的进入到该方法中可以详细了解。
二、伪代码执行流程
NameNode.main() // 入口函数
|——createNameNode(); // 通过new NameNode()进行实例化
|——initialize(); // 方法进行初始化操作
|——startHttpServer(); // 启动HttpServer
|——loadNamesystem(); // 加载元数据
|——loadFromDisk(); // 从磁盘加载数据
|——new FSImage(); // 实例化FSImage对象
|——new FSNamesystem(fsImage); // 根据FSImage对象实例化FSNamesystem
|——loadFSImage(startOpt); // 加载并合并fsimage、edits,然后写出到磁盘
|——join()
三、代码图解
Hadoop源码学习笔记之NameNode启动场景流程三:FSNamesystem初始化源码剖析的更多相关文章
- Hadoop源码学习笔记之NameNode启动场景流程四:rpc server初始化及启动
老规矩,还是分三步走,分别为源码调用分析.伪代码核心梳理.调用关系图解. 一.源码调用分析 根据上篇的梳理,直接从initialize()方法着手.源码如下,部分代码的功能以及说明,已经在注释阐述了. ...
- Hadoop源码学习笔记之NameNode启动场景流程二:http server启动源码剖析
NameNodeHttpServer启动源码剖析,这一部分主要按以下步骤进行: 一.源码调用分析 二.伪代码调用流程梳理 三.http server服务流程图解 第一步,源码调用分析 前一篇文章已经锁 ...
- Hadoop源码学习笔记之NameNode启动场景流程五:磁盘空间检查及安全模式检查
本篇内容关注NameNode启动之前,active状态和standby状态的一些后台服务及准备工作,即源码里的CommonServices.主要包括磁盘空间检查. 可用资源检查.安全模式等.依然分为三 ...
- Hadoop源码学习笔记之NameNode启动场景流程一:源码环境搭建和项目模块及NameNode结构简单介绍
最近在跟着一个大佬学习Hadoop底层源码及架构等知识点,觉得有必要记录下来这个学习过程.想到了这个废弃已久的blog账号,决定重新开始更新. 主要分以下几步来进行源码学习: 一.搭建源码阅读环境二. ...
- JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析
JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...
- (三)Netty源码学习笔记之boss线程处理流程
尊重原创,转载注明出处,原文地址:http://www.cnblogs.com/cishengchongyan/p/6160194.html 本文我们将先从NioEventLoop开始来学习服务端的 ...
- Spring源码学习笔记12——总结篇,IOC,Bean的生命周期,三大扩展点
Spring源码学习笔记12--总结篇,IOC,Bean的生命周期,三大扩展点 参考了Spring 官网文档 https://docs.spring.io/spring-framework/docs/ ...
- async-validator 源码学习笔记(六):validate 方法
系列文章: 1.async-validator 源码学习(一):文档翻译 2.async-validator 源码学习笔记(二):目录结构 3.async-validator 源码学习笔记(三):ru ...
- Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构
Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...
随机推荐
- JDK1.9怎么配置环境变量
- 没有对比就没有伤害,memcache and redis
Memcached 与 Redis 的关键性能指标比较 性能对比: Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis在存储小数据时比 Memcached 性 ...
- sql查询学习和实践点滴积累
https://blog.rjmetrics.com/2008/10/28/correlated-subqueries-in-mysql/ http://www.mysqltutorial.org/m ...
- ASP.NET错误处理的方式(一)
对Web应用程序来说,发生不可预知的错误和异常在所难免,我们必须为Web程序提供错误处理机制.当错误发生时,我们必须做好两件事情:一是将错误信息记录日志,发邮件通知网站维护人员,方便技术人员对错误进行 ...
- Python学习---django之Model语法180124
django之Model语法[Models] 1 django默认支持sqlite,mysql, oracle,postgresql数据库. <1> sqlite django默认使 ...
- [COGS 2065]学数数
2065. 学数数 ★★★☆ 输入文件:jxthree.in 输出文件:jxthree.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] 从前有一只咩,还有一只叽 ...
- linux性能系列--内存
一.啥是内存呢? 回答:内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁.计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大. 内存(Memory)也被称为内存储器, ...
- Python常用库之三:Matplotlib
导入模块 import matplotlib.pyplot as plt import seaborn as sb 绘制条形图 countplot(data:数据集, x:x坐标轴, color:条形 ...
- 随手练——洛谷-P1008 / P1618 三连击(暴力搜索)
1.普通版 第一眼看到这个题,我脑海里就是,“我们是不是在哪里见过~”,去年大一刚学C语言的时候写过一个类似的题目,写了九重循环....就像这样(在洛谷题解里看到一位兄台写的....超长警告,慎重点开 ...
- Kali-linux Gerix Wifi Cracker破解无线网络
Gerix Wifi Cracker是另一个aircrack图形用户界面的无线网络破解工具.本节将介绍使用该工具破解无线网络及创建假的接入点. 9.3.1 Gerix破解WEP加密的无线网络 在前面介 ...