【Hadoop】nameNode啟動(dòng)過(guò)程源碼分析
簡(jiǎn)介
本章詳細介紹NameNode啟動(dòng)過(guò)程。主要是代碼級別的解釋。
nameNode的啟動(dòng)主要是有NameNode.java主導的,由main函數開(kāi)始了解。
下面是main函數里面的主要內容,可以看到主要由createNameNode實(shí)現NameNode的啟動(dòng)。
NameNode namenode = createNameNode(argv, null);
if (namenode != null) {
namenode.join();
}
在createNameNode函數里面主要是分為兩部分:
-
參數解析:主要關(guān)心解析startOpt,startOpt可以控制具體操作,比如format、rockback等。主要操作如下,后續會(huì )詳細介紹。
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");
模型情況下會(huì )走到啟動(dòng)的啟動(dòng)的流程里面。
-
啟動(dòng)NameNode或者其他操作,比如format等。
啟動(dòng)
NameNode的核心主要在NameNode的構造函數里面。
this.haEnabled = HAUtil.isHAEnabled(conf, nsId);
// 檢查HA的狀態(tài),主要是判斷當前啟動(dòng)的是主實(shí)例還是備實(shí)例
state = createHAState(getStartupOption(conf));
this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf);
this.haContext = createHAContext();
try {
initializeGenericKeys(conf, nsId, namenodeId);
// 啟動(dòng)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函數詳解如下:
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合并產(chǎn)生新的FSImage
loadNamesystem(conf);
//TODO 待確認用途
startAliasMapServerIfNecessary(conf);
//創(chuàng )建rpcserver,封裝了NameNodeRpcServer、ClientRPCServer
//支持ClientNameNodeProtocol、DataNodeProtocolPB等協(xié)議
rpcServer = createRpcServer(conf);
initReconfigurableBackoffKey();
// .... 省略
if (NamenodeRole.NAMENODE == role) {
httpServer.setNameNodeAddress(getNameNodeAddress());
httpServer.setFSImage(getFSImage());
if (levelDBAliasMapServer != null) {
httpServer.setAliasMap(levelDBAliasMapServer.getAliasMap());
}
}
//啟動(dòng)執行多個(gè)重要的工作線(xiàn)程
startCommonServices(conf);
startMetricsLogger(conf);
}
startCommonServices函數詳解
啟動(dòng)NameNode關(guān)鍵服務(wù)
private void startCommonServices(Configuration conf) throws IOException {
// 創(chuàng )建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());
}
}
// 啟動(dòng)rpc服務(wù)
rpcServer.start();
try {
// 獲取啟動(dòng)插件列表
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;
}
// 啟動(dòng)所有插件
for (ServicePlugin p: plugins) {
try {
// 調用插件的start接口,需要插件自己實(shí)現,需要實(shí)現接口ServicePlugin
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
在當前函數中啟動(dòng)blockManager和NameNodeResourceChecker,blockManager比較關(guān)鍵。
void startCommonServices(Configuration conf, HAContext haContext) throws IOException {
this.registerMBean(); // register the MBean for the FSNamesystemState
writeLock();
this.haContext = haContext;
try {
//創(chuàng )建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);
// 激活blockManager,blockManager負責管理文件系統中文件的物理塊與實(shí)際存儲位置的映射關(guān)系,
// 是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
啟動(dòng)blockManager.activate 主要是初始化blockManager。
主要包含下面幾個(gè)方面:
- pendingReconstruction
- datanodeManager
- bmSafeMode
public void activate(Configuration conf, long blockTotal) {
pendingReconstruction.start();
// 初始化datanodeManager
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);
}
您好,看你的站做的挺不錯的,有沒(méi)有出手的打算,想出手的話(huà),聯(lián)系QQ1587894193。
你好,看完你的博客文章,感覺(jué)很不錯!希望與你網(wǎng)站首頁(yè)友情鏈接
流量卡知識網(wǎng)
http://53go.cn/
專(zhuān)注于移動(dòng) / 聯(lián)通 / 電信運營(yíng)商官方推出的大流量多語(yǔ)音活動(dòng)長(cháng)短期套餐手機卡的相關(guān)知識的介紹普及
首先我得要搞明白NameNode是干什么用的