NameNode启动源码分析 #7

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

View File

@ -1,5 +1,5 @@
## 简介 # 简介
本章详细介绍NameNode启动过程。主要是代码级别的解释。 本章详细介绍NameNode启动过程。主要是代码级别的解释。
@ -41,7 +41,7 @@ if (namenode != null) {
模型情况下会走到启动的启动的流程里面。 模型情况下会走到启动的启动的流程里面。
- 启动NameNode或者其他操作比如format等。 - 启动NameNode或者其他操作比如format等。
### 启动 ## 启动
NameNode的核心主要在NameNode的构造函数里面。 NameNode的核心主要在NameNode的构造函数里面。
@ -120,3 +120,116 @@ protected void initialize(Configuration conf) throws IOException {
startMetricsLogger(conf); startMetricsLogger(conf);
} }
``` ```
### startCommonServices函数详解
启动NameNode关键服务
```java
private void startCommonServices(Configuration conf) throws IOException {
// 创建NameNodeResourceChecker、激活BlockManager等
namesystem.startCommonServices(conf, haContext);
registerNNSMXBean();
if (NamenodeRole.NAMENODE != role) {
startHttpServer(conf);
httpServer.setNameNodeAddress(getNameNodeAddress());
httpServer.setFSImage(getFSImage());
if (levelDBAliasMapServer != null) {
httpServer.setAliasMap(levelDBAliasMapServer.getAliasMap());
}
}
// 启动rpc服务
rpcServer.start();
try {
// 获取启动插件列表
plugins = conf.getInstances(DFS_NAMENODE_PLUGINS_KEY,
ServicePlugin.class);
} catch (RuntimeException e) {
String pluginsValue = conf.get(DFS_NAMENODE_PLUGINS_KEY);
LOG.error("Unable to load NameNode plugins. Specified list of plugins: " +
pluginsValue, e);
throw e;
}
// 启动所有插件
for (ServicePlugin p: plugins) {
try {
p.start(this);
} catch (Throwable t) {
LOG.warn("ServicePlugin " + p + " could not be started", t);
}
}
LOG.info(getRole() + " RPC up at: " + getNameNodeAddress());
if (rpcServer.getServiceRpcAddress() != null) {
LOG.info(getRole() + " service RPC up at: "
+ rpcServer.getServiceRpcAddress());
}
}
```
### namesystem.startCommonServices
在当前函数中启动blockManager和NameNodeResourceCheckerblockManager比较关键。
```java
void startCommonServices(Configuration conf, HAContext haContext) throws IOException {
this.registerMBean(); // register the MBean for the FSNamesystemState
writeLock();
this.haContext = haContext;
try {
//创建NameNodeResourceChecker并立即检查一次
nnResourceChecker = new NameNodeResourceChecker(conf);
checkAvailableResources();
assert !blockManager.isPopulatingReplQueues();
StartupProgress prog = NameNode.getStartupProgress();
prog.beginPhase(Phase.SAFEMODE);
//获取已完成的数据块总量
long completeBlocksTotal = getCompleteBlocksTotal();
prog.setTotal(Phase.SAFEMODE, STEP_AWAITING_REPORTED_BLOCKS,
completeBlocksTotal);
// 激活blockManagerblockManager负责管理文件系统中文件的物理块与实际存储位置的映射关系
// 是NameNode的核心功能之一。
blockManager.activate(conf, completeBlocksTotal);
} finally {
writeUnlock("startCommonServices");
}
registerMXBean();
DefaultMetricsSystem.instance().register(this);
if (inodeAttributeProvider != null) {
inodeAttributeProvider.start();
dir.setINodeAttributeProvider(inodeAttributeProvider);
}
// 注册快照管理器
snapshotManager.registerMXBean();
InetSocketAddress serviceAddress = NameNode.getServiceAddress(conf, true);
this.nameNodeHostName = (serviceAddress != null) ?
serviceAddress.getHostName() : "";
}
```
### blockManager.activate
启动blockManager.activate 主要是初始化blockManager。
主要包含下面几个方面:
- pendingReconstruction
- datanodeManager
- bmSafeMode
```java
public void activate(Configuration conf, long blockTotal) {
pendingReconstruction.start();
datanodeManager.activate(conf);
this.redundancyThread.setName("RedundancyMonitor");
this.redundancyThread.start();
this.markedDeleteBlockScrubberThread.setName("MarkedDeleteBlockScrubberThread");
this.markedDeleteBlockScrubberThread.start();
this.blockReportThread.start();
mxBeanName = MBeans.register("NameNode", "BlockStats", this);
bmSafeMode.activate(blockTotal);
}
```