NameNode启动流程
- 准备工作
- 1. 概述
- 2. 解析
- main→createNameNode→new NameNode→initialize→
- (1)startHttpServer
- (2)loadNamesystem
- (3)createRpcServer
- (4)startCommonServices→NameNodeResourceChecker、checkAvailableResources
- (5)startCommonServices→blockManager.active()→heartbeatManager.active()
- (6)startCommonServices→blockManager.active()→bmSafeMode.active(blockTotal)
准备工作
首先在Maven中导入Hadoop相关依赖,这里用的是hadoop 3.1.3版本:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.abc</groupId>
<artifactId>Hdfs</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs-client</artifactId>
<version>3.1.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.30</version>
</dependency>
</dependencies>
</project>
1. 概述
如图,NameNode启动时,主要的几个步骤分别是:
startHttpServer
启动9870端口服务;loadNamesystem
从磁盘加载镜像文件fsimage和edits编辑日志;createRpcServer
创建RPC服务端checkAvailableResources
检查磁盘空间是否充足datanodeManager.activate
心跳超时判断bmSafeMode.avtive
安全模式
2. 解析
main→createNameNode→new NameNode→initialize→
NameNode主要的几个步骤,都是在initialize
方法中完成,所以先找到initialize:
先找到NameNode类的main()
方法,以及createNameNode
:
createNameNode拉到最下面,有new NameNode,进入NameNode
:
进入NameNode,有initialize()
方法:
(1)startHttpServer
进入initialize
方法:
调用start()
开启httpServer:
(2)loadNamesystem
进入initialize中的loadNamesystem
方法,再进入loadFromDisk
从磁盘加载镜像文件FSImage
和编辑日志Edits
:
(3)createRpcServer
进入initialize中的createRpcServer
开启RPC服务端
(4)startCommonServices→NameNodeResourceChecker、checkAvailableResources
进入initialize中的startCommonServices
调用重载的startCommonServices
:
在NameNodeResourceChecker
中检查镜像文件和编辑日志的路径是否能存储100mb内容,即1024x1024x100=104857600;
如果不够会警告;
在checkAvailableResources
中判断磁盘是否够用,不够则false;
isResourceAvailable()方法来自一个接口,
退到areResourceAvailable中,Ctrl+Alt+B 找到CheckableNameNodeResource() 接口的实现类:
判断磁盘空间是否够用,duReserved
就是defaultValue即100mb,不足则会false:
(5)startCommonServices→blockManager.active()→heartbeatManager.active()
退回startCommonServices,
进入blockManager.active()
:
进入heartbeatManager.activate
:
进入heartbeatManager是一个heartbeatThread线程:
调用heartbeatThread线程的start()方法,则找run()方法!
进入heartbeatCheck():
判断是否是10分钟30秒
判断时间: 25+ 100010*3s,超过即视为DataNode挂掉:
(6)startCommonServices→blockManager.active()→bmSafeMode.active(blockTotal)
返回blockManager.active()
进入bmSafeMode.active(blockTotal)
:
如果areThreasholdsMet()为true,则离开安全模式,否则进入安全模式;
①setBlockTotal
设置块的阀值:
threshold也是阀值,是0.999,即总的块假设为1000个,则只要有999个都启动即允许有一个不启动,则可以正常
blockthrehold = 总块数*0.999
②areThreasholdsMet()
判断正常启动的块是否大于了阀值blockThrehold,如果块大于了blockThrehold阀值,则返回true;
到此,NameNode启动过程中的六大步骤完毕。