上篇内容分析了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账号,决定重新开始更新. 主要分以下几步来进行源码学习: 一.搭建源码阅读环境二. ...
-
(三)Netty源码学习笔记之boss线程处理流程
尊重原创,转载注明出处,原文地址:http://www.cnblogs.com/cishengchongyan/p/6160194.html 本文我们将先从NioEventLoop开始来学习服务端的 ...
-
Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构
Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...
-
Hadoop源码学习笔记(6)——从ls命令一路解剖
Hadoop源码学习笔记(6) ——从ls命令一路解剖 Hadoop几个模块的程序我们大致有了点了解,现在我们得细看一下这个程序是如何处理命令的. 我们就从原头开始,然后一步步追查. 我们先选中ls命 ...
-
Hadoop源码学习笔记(2) ——进入main函数打印包信息
Hadoop源码学习笔记(2) ——进入main函数打印包信息 找到了main函数,也建立了快速启动的方法,然后我们就进去看一看. 进入NameNode和DataNode的主函数后,发现形式差不多: ...
-
Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类
Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何 ...
随机推荐
-
Nandflash 驱动移植
前段时间,研究了一下4G的Nandflash驱动.手头上只有飞凌6410BSP自带的Nandflash驱动,该驱动不支持K9GAG08U0D(2G)和K9LBG08U0D(4G)的Nandflash. ...
-
gentoo
http://www.aboutyun.com/thread-8522-1-1.html .java.io.IOException: Connection reset by peer c ...
-
IIS7和IIS7.5备份和还原的方法
windows2008的iis配置备份和iis6不同,在iis7中没有了6原来的保存配置xml的选项,而采用的是dos命令来进行iis7的备份.以下是win2008上iis7备份的方法. 首先打开CM ...
-
【ESP8266】发送HTTP请求
一.ESP8266简介 ESP8266 是深圳安信可科技有限公司开发的基于乐鑫ESP8266的超低功耗的UART-WIFI模块的模组,可以方便进行二次元开发,接入云端服务,实现手机3/4G全球随时随地 ...
-
Lombok 使用小结
Lombok 简介 Lombok 是一种 Java 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注释实现这一目的.通过在开发环境中实现 Lo ...
-
让DIV随滚动条滚动
$(window).scroll(function(event){ //JQ监听滚动条 $('DIV').css("top", $(window).scrollTop ...
-
sqoop导出到hdfs
./sqoop export --connect jdbc:mysql://192.168.58.180/db --username root --password 123456 --export- ...
-
【SMTP】常见错误码
'* 邮件服务返回代码含义 '* 500 格式错误,命令不可识别(此错误也包括命令行过长) '* 501 参数格式错误 '* 502 命令不可实现 '* 503 错误的命令序列 '* 504 命令参数 ...
-
Vxlan学习笔记——实现
1. 创建NVI NVI(Network Virtual Instance)网络虚拟实例,是VTEP上为一个VXLAN提供L2交换服务的虚拟交换实例,NVI和VXLAN ID一一对应.别和VNI混了. ...
-
OpenEXR的读取机制
这还是一篇学习笔记,知识重点还是领会完再敲一遍比较好. OpenEXR通过RgbaInputFile这个接口读取RGBA ONLY图像文件信息,该接口通过dataWindow()方法获取图像边界坐标信 ...