NameNode启动源码分析 #7

Merged
zeekling merged 3 commits from namenode into master 2023-11-05 04:00:12 +00:00
Showing only changes of commit cb3add4f33 - Show all commits

View File

@ -0,0 +1,122 @@
## 简介
本章详细介绍NameNode启动过程。主要是代码级别的解释。
nameNode的启动主要是有NameNode.java主导的由main函数开始了解。
下面是main函数里面的主要内容可以看到主要由createNameNode实现NameNode的启动。
```java
NameNode namenode = createNameNode(argv, null);
if (namenode != null) {
namenode.join();
}
```
在createNameNode函数里面主要是分为两部分
- 参数解析主要关心解析startOptstartOpt可以控制具体操作比如format、rockback等。主要操作如下,后续会详细介绍。
```java
FORMAT ("-format"),
CLUSTERID ("-clusterid"),
GENCLUSTERID ("-genclusterid"),
REGULAR ("-regular"),
BACKUP ("-backup"),
CHECKPOINT("-checkpoint"),
UPGRADE ("-upgrade"),
ROLLBACK("-rollback"),
ROLLINGUPGRADE("-rollingUpgrade"),
IMPORT ("-importCheckpoint"),
BOOTSTRAPSTANDBY("-bootstrapStandby"),
INITIALIZESHAREDEDITS("-initializeSharedEdits"),
RECOVER ("-recover"),
FORCE("-force"),
NONINTERACTIVE("-nonInteractive"),
SKIPSHAREDEDITSCHECK("-skipSharedEditsCheck"),
RENAMERESERVED("-renameReserved"),
METADATAVERSION("-metadataVersion"),
UPGRADEONLY("-upgradeOnly"),
HOTSWAP("-hotswap"),
OBSERVER("-observer");
```
模型情况下会走到启动的启动的流程里面。
- 启动NameNode或者其他操作比如format等。
### 启动
NameNode的核心主要在NameNode的构造函数里面。
```java
this.haEnabled = HAUtil.isHAEnabled(conf, nsId);
// 检查HA的状态主要是判断当前启动的是主实例还是备实例
state = createHAState(getStartupOption(conf));
this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf);
this.haContext = createHAContext();
try {
initializeGenericKeys(conf, nsId, namenodeId);
// 启动NameNode
initialize(getConf());
state.prepareToEnterState(haContext);
try {
haContext.writeLock();
state.enterState(haContext);
} finally {
haContext.writeUnlock();
}
} catch (IOException e) {
this.stopAtException(e);
throw e;
} catch (HadoopIllegalArgumentException e) {
this.stopAtException(e);
throw e;
}
```
initialize函数详解如下
```java
protected void initialize(Configuration conf) throws IOException {
// .... 省略
//登录kerberos
UserGroupInformation.setConfiguration(conf);
loginAsNameNodeUser(conf);
// 初始化监控信息
NameNode.initMetrics(conf, this.getRole());
StartupProgressMetrics.register(startupProgress);
pauseMonitor = new JvmPauseMonitor();
pauseMonitor.init(conf);
pauseMonitor.start();
metrics.getJvmMetrics().setPauseMonitor(pauseMonitor);
// .... 省略
if (NamenodeRole.NAMENODE == role) {
startHttpServer(conf);
}
// 从本地加载FSImage并且与Editlog合并产生新的FSImage
loadNamesystem(conf);
//TODO 待确认用途
startAliasMapServerIfNecessary(conf);
//创建rpcserver封装了NameNodeRpcServer、ClientRPCServer
//支持ClientNameNodeProtocol、DataNodeProtocolPB等协议
rpcServer = createRpcServer(conf);
initReconfigurableBackoffKey();
// .... 省略
if (NamenodeRole.NAMENODE == role) {
httpServer.setNameNodeAddress(getNameNodeAddress());
httpServer.setFSImage(getFSImage());
if (levelDBAliasMapServer != null) {
httpServer.setAliasMap(levelDBAliasMapServer.getAliasMap());
}
}
//启动执行多个重要的工作线程
startCommonServices(conf);
startMetricsLogger(conf);
}
```