NameNode 架构图解

用户头像
大数据学徒
关注
发布于: 2020 年 07 月 27 日
NameNode架构图解

本文档基于Hadoop 2.7.0

开发环境:Ubuntu/Mac + Intellij IDEA,Hadoop依赖已安装。

IntelliJ IDEA 中我用的比较多的两个快捷键:快速双击Shift搜索类,Ctrl/Command+7 查看类成员。



如前文所说,搭建好开发环境后,开始学习 HDFS 相关原理,本文介绍组成NameNode的各个部分的基本功能,以及它们之间的联系。



不关心细节的话,可以直接跳到最后看“总结”。

前言



目前我认为 MiniDFSCluster 是一个很好的着手点,通过它可以直接在IDEA里启动HDFS的各种组件,从而方便进行调试。



不过它只是一个工具类,它能够在单进程里启动一个集群,当然需要做一些配置初始化和其它脏活,但这些其实对我来说没啥大用,我直接通过它跳到NameNode的代码。

MiniDFSCluster如何启动NameNode



因为是源码阅读和分析,细碎繁琐是免不了的,我的分析可能会省略很多细节,我感觉要么自己过一遍,要么跳过分析过程,直接看总结的关键信息会比较科学。



MiniDFSCluster类的启动方式是用它内部的Builder类进行build,这是一种设计模式,在它的build方法里,它创建MiniDFSCluster对象:

/**
* Construct the actual MiniDFSCluster
*/
public MiniDFSCluster build() throws IOException {
return new MiniDFSCluster(this);
}

那么再看MiniDFSCluster的构造函数,在构造函数里,进行了一堆参数校验和准备之后,调用了initMiniDFSCluster 方法,在这个方法里,又调用了 createNameNodesAndSetConf 方法,同样的,在一系列参数校验之后,调用了 createNameNode 方法,在这个方法里,终于调用到了NameNode的createNameNode方法:

private void createNameNode(...) {
// ...
NameNode nn = NameNode.createNameNode(args, conf);
// ...
}

这个调用方法和真正的NameNode启动方式(NameNode类的 main 方法)是一样的:

public static void main(String argv[]) throws Exception {
// ...
NameNode namenode = createNameNode(argv, null);
if (namenode != null) {
namenode.join();
// ...
}

令人振奋,说明这个方法就是创建NameNode对象的标准方法,到此,和MiniDFSCluster说再见,下面进入NameNode的代码。

NameNode 的启动流程

createNameNode 方法,里面有一个 switch

switch(startOpt) {
case FORMAT: {
// ...
}
default: {
// 初始化NameNode的指标系统,还没有深入看,应该包括NameNode的Web UI里看到的指标和JMX指标
DefaultMetricsSystem.initialize("NameNode");
return new NameNode(conf);
}
}

沿着NameNode的构造函数往下看,会发现里面有一个 initialize 函数比较关键,核心逻辑如下:

protected void initialize(Configuration conf) throws IOException {
//在启用了Kerberos认证的情况下进行认证,否则是个空操作
UserGroupInformation.setConfiguration(conf);
loginAsNameNodeUser(conf);
// 为active namenode启动 http 服务
startHttpServer(conf);
// 加载文件系统
loadNamesystem(conf);
// 创建RPC服务
rpcServer = createRpcServer(conf);
// JVM pause 监控
pauseMonitor = new JvmPauseMonitor(conf);
pauseMonitor.start();
metrics.getJvmMetrics().setPauseMonitor(pauseMonitor);
// 启动RPC服务和文件系统服务,这里单独封装一个函数看起来比较奇怪,不管它
startCommonServices(conf);
}

initialize 函数里可以看到NameNode的组件(其实还有其它的组件,但是这些比较主要,其它的后面看到了再说):

  1. 文件系统,即FSNamesystem对象;

  2. RPC服务,即NameNodeRpcServer对象;

  3. HTTP服务,即NameNodeHttpServer对象;

  4. 监控线程,即JvmPauseMonitor对象;

  5. Metrics,即NameNodeMetrics对象;

NameNode各组件介绍

通过类注释和搜索引擎简单了解这5个组件的功能。

文件系统FSNameSystem

/***************************************************
* FSNamesystem does the actual bookkeeping work for the
* DataNode.
*
* It tracks several important tables.
*
* 1) valid fsname --> blocklist (kept on disk, logged)
* 2) Set of all valid blocks (inverted #1)
* 3) block --> machinelist (kept in memory, rebuilt dynamically from reports)
* 4) machine --> blocklist (inverted #2)
* 5) LRU cache of updated-heartbeat machines
***************************************************/

从注释上看,FSNameSystem 的功能是维护文件和块的映射关系、块和datanode的映射关系以及机器的状态,是NameNode最核心的数据结构。

RPC服务NameNodeRPCServer

/**
* This class is responsible for handling all of the RPC calls to the NameNode.
* It is created, started, and stopped by {@link NameNode}.
*/

NameNodeRPCServer负责处理NameNode收到的所有RPC请求,包括DataNode和Client。

HTTP服务NameNodeHttpServer

/**
* Encapsulates the HTTP server started by the NameNode.
*/

NameNodeHttpServer 封装了NameNode的HTTP服务,HTTP服务包含了Web UI、WebHDFS和其它API。

监控线程JvmPauseMonitor

/**
* Class which sets up a simple thread which runs in a loop sleeping
* for a short interval of time. If the sleep takes significantly longer
* than its target time, it implies that the JVM or host machine has
* paused processing, which may cause other problems. If such a pause is
* detected, the thread logs a message.
*/

JvmPauseMonitor 的作用是,通过不停的sleep,比较预期sleep的时间和实际sleep的时间,来判断JVM或者机器是否有长时间的暂停,这种线程在很多其它软件中也存在,比如Zookeeper,Impala,Hbase等。

Metrics数据结构NameNodeMetrics

/**
* This class is for maintaining the various NameNode activity statistics
* and publishing them through the metrics interfaces.
*/

NameNodeMetrics 维护了文件系统状态及操作的统计信息和JVM指标,可以通过HTTP或JMX访问。

总结

NameNode内部架构



我将目前我所了解到的NameNode架构总结成上图,加上以下文字说明:

  1. NameNode最核心的数据结构是文件系统,它维护了文件、块和datanode的信息,NameNode的RPC服务通过接收客户端和datanode的请求,对文件系统进行更新;

  2. 在RPC服务之外,NameNode还提供了HTTP服务,也可以用于访问文件系统;

  3. NameNode还维护了一系列监控指标,指标包括了文件系统的统计信息和JVM相关指标,这些指标可以通过HTTP或JMX接口进行访问。

  4. 在核心线程之外,NameNode还有一个专门用于监控进程暂停时间的线程。



本文完,欢迎批评指正,交流建议。



公众号:大数据学徒



发布于: 2020 年 07 月 27 日 阅读数: 50
用户头像

大数据学徒

关注

活到秃学到秃 2019.01.08 加入

专注大数据运维开发

评论

发布
暂无评论
NameNode架构图解