Skip to content

Commit 024a19d

Browse files
committed
apache#1. namenode的启动流程
1 parent f95b390 commit 024a19d

File tree

2 files changed

+56
-4
lines changed

2 files changed

+56
-4
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,9 @@ private void loadFSImage(StartupOption startOpt) throws IOException {
973973
// We shouldn't be calling saveNamespace if we've come up in standby state.
974974
MetaRecoveryContext recovery = startOpt.createRecoveryContext();
975975
final boolean staleImage
976+
// namenode 启动
977+
// fsimage + editlog = new fsImage
978+
// TODO (1)合并元数据
976979
= fsImage.recoverTransitionRead(startOpt, this, recovery);
977980
if (RollingUpgradeStartupOption.ROLLBACK.matches(startOpt) ||
978981
RollingUpgradeStartupOption.DOWNGRADE.matches(startOpt)) {
@@ -983,6 +986,7 @@ private void loadFSImage(StartupOption startOpt) throws IOException {
983986
+ " (staleImage=" + staleImage + ", haEnabled=" + haEnabled
984987
+ ", isRollingUpgrade=" + isRollingUpgrade() + ")");
985988
if (needToSave) {
989+
// TODO (2) 把合并出来的新的fsimage写到我们的磁盘上面
986990
fsImage.saveNamespace(this);
987991
} else {
988992
updateStorageVersionForRollingUpgrade(fsImage.getLayoutVersion(),
@@ -996,6 +1000,7 @@ private void loadFSImage(StartupOption startOpt) throws IOException {
9961000
// we shouldn't do it when coming up in standby state
9971001
if (!haEnabled || (haEnabled && startOpt == StartupOption.UPGRADE)
9981002
|| (haEnabled && startOpt == StartupOption.UPGRADEONLY)) {
1003+
// TODO (3) 打开新的editlog开始写日志
9991004
fsImage.openEditLogForWrite();
10001005
}
10011006
success = true;
@@ -1049,19 +1054,24 @@ private void stopSecretManager() {
10491054

10501055
/**
10511056
* Start services common to both active and standby states
1057+
* 1) fsimage -> 目录,磁盘存储够不够(100M)
1058+
* 2)editlog -> 目录,磁盘存储够不够
10521059
*/
10531060
void startCommonServices(Configuration conf, HAContext haContext) throws IOException {
10541061
this.registerMBean(); // register the MBean for the FSNamesystemState
10551062
writeLock();
10561063
this.haContext = haContext;
10571064
try {
1065+
// NameNode资源检查 通过hdfs-site.xml, core-site.xml 两个文件找到fsimage, editlog的目录
10581066
nnResourceChecker = new NameNodeResourceChecker(conf);
1067+
// 判断路径是否有足够的可用空间
10591068
checkAvailableResources();
10601069
assert safeMode != null && !isPopulatingReplQueues();
10611070
StartupProgress prog = NameNode.getStartupProgress();
10621071
prog.beginPhase(Phase.SAFEMODE);
10631072
prog.setTotal(Phase.SAFEMODE, STEP_AWAITING_REPORTED_BLOCKS,
10641073
getCompleteBlocksTotal());
1074+
// TODO 设置安全模式
10651075
setBlockTotal();
10661076
blockManager.activate(conf);
10671077
} finally {
@@ -5264,6 +5274,10 @@ private synchronized boolean canLeave() {
52645274
/**
52655275
* There is no need to enter safe mode
52665276
* if DFS is empty or {@link #threshold} == 0
5277+
* TODO 触发安全模式的三个条件:
5278+
* 1. complete block的个数高于threshold
5279+
* 2, datanode的个数高于 DFS_NAMENODE_SAFEMODE_MIN_DATANODES_KEY = "dfs.namenode.safemode.min.datanodes"
5280+
* 3. 存放fsimage editlog的目录下面的大小高于100m
52675281
*/
52685282
private boolean needEnter() {
52695283
return (threshold != 0 && blockSafe < blockThreshold) ||
@@ -5272,7 +5286,8 @@ private boolean needEnter() {
52725286
}
52735287

52745288
/**
5275-
* Check and trigger safe mode if needed.
5289+
* Check and trigger safe mode if needed.
5290+
* TODO 检查是否进入安全模式
52765291
*/
52775292
private void checkMode() {
52785293
// Have to have write-lock since leaving safemode initializes
@@ -5283,6 +5298,7 @@ private void checkMode() {
52835298
}
52845299
// if smmthread is already running, the block threshold must have been
52855300
// reached before, there is no need to enter the safe mode again
5301+
// TODO needEnter =》 检查是否进入安全模式
52865302
if (smmthread == null && needEnter()) {
52875303
enter();
52885304
// check if we are ready to initialize replication queues
@@ -5344,6 +5360,8 @@ private synchronized void setBlockTotal(int total) {
53445360
*/
53455361
private synchronized void incrementSafeBlockCount(short replication) {
53465362
if (replication == safeReplication) {
5363+
// datanode 会进行block的汇报
5364+
// 每次汇报后blocksafe就会 自增
53475365
this.blockSafe++;
53485366

53495367
// Report startup progress only if we haven't completed startup yet.
@@ -5679,6 +5697,7 @@ public void setBlockTotal() {
56795697
SafeModeInfo safeMode = this.safeMode;
56805698
if (safeMode == null)
56815699
return;
5700+
// getCompleteBlocksTotal 获取所有正常的block的个数
56825701
safeMode.setBlockTotal((int)getCompleteBlocksTotal());
56835702
}
56845703

@@ -5694,6 +5713,10 @@ public long getBlocksTotal() {
56945713
/**
56955714
* Get the total number of COMPLETE blocks in the system.
56965715
* For safe mode only complete blocks are counted.
5716+
*
5717+
* TODO 在HDFS集群里面block的状态分为两种类型
5718+
* 1)complete类型:正常的可用的block
5719+
* 2)underconstruction类型: 处于正在构建的block
56975720
*/
56985721
private long getCompleteBlocksTotal() {
56995722
// Calculate number of blocks under construction

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/NameNode.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,8 @@
137137
* is a second backup/failover NameNode, or when using federated NameNodes.)
138138
*
139139
* The NameNode controls two critical tables:
140-
* 1) filename->blocksequence (namespace)
141-
* 2) block->machinelist ("inodes")
140+
* 1) filename->blocksequence (namespace) 文件与文件块(block)的关系, 这张表存储在了磁盘上面
141+
* 2) block->machinelist ("inodes") : 文件块与之间的关系,每次NameNode 重启后会重新构建出来
142142
*
143143
* The first table is stored on disk and is very precious.
144144
* The second table is rebuilt every time the NameNode comes up.
@@ -149,6 +149,17 @@
149149
* with exposing the IPC interface and the HTTP server to the outside world,
150150
* plus some configuration management.
151151
*
152+
* NameNode 服务是由三个重要的类支撑的:
153+
* 1)NameNode类:
154+
* 管理配置的参数:hdfs-site.xml, core-site.xml
155+
* 2) NameNode Server:
156+
* IPC server:
157+
* NameNodeRPCServer: 开放端口,等待别人调用,比如:8020/9000
158+
* HTTP server:
159+
* NameNodeHttpServer: 开放50070界面,我们可以通过这个界面了解HDFS的情况
160+
* 3)FSNameSystem:
161+
* 这个类很重要,管理了HDFS的元数据
162+
*
152163
* NameNode implements the
153164
* {@link org.apache.hadoop.hdfs.protocol.ClientProtocol} interface, which
154165
* allows clients to ask for DFS services.
@@ -635,13 +646,18 @@ protected void initialize(Configuration conf) throws IOException {
635646
StartupProgressMetrics.register(startupProgress);
636647

637648
if (NamenodeRole.NAMENODE == role) {
649+
// TODO 启动HttpServer
638650
startHttpServer(conf);
639651
}
640652

641653
this.spanReceiverHost = SpanReceiverHost.getInstance(conf);
642654

655+
/**
656+
* TODO 加载元数据
657+
*/
643658
loadNamesystem(conf);
644659

660+
// TODO 启动RPCserver
645661
rpcServer = createRpcServer(conf);
646662
if (clientNamenodeAddress == null) {
647663
// This is expected for MiniDFSCluster. Set it now using
@@ -659,7 +675,9 @@ protected void initialize(Configuration conf) throws IOException {
659675
pauseMonitor = new JvmPauseMonitor(conf);
660676
pauseMonitor.start();
661677
metrics.getJvmMetrics().setPauseMonitor(pauseMonitor);
662-
678+
// TODO 启动一些公共的服务。NameNode RPC的服务就是在里面启动的
679+
// 1)进行资源检查,检查是否有磁盘足够存储元数据
680+
// 2)进入安全模式检查,检查是否可以退出安全模式
663681
startCommonServices(conf);
664682
}
665683

@@ -674,6 +692,7 @@ protected NameNodeRpcServer createRpcServer(Configuration conf)
674692

675693
/** Start the services common to active and standby states */
676694
private void startCommonServices(Configuration conf) throws IOException {
695+
// TODO 元数据管理
677696
namesystem.startCommonServices(conf, haContext);
678697
registerNNSMXBean();
679698
if (NamenodeRole.NAMENODE != role) {
@@ -807,6 +826,7 @@ protected NameNode(Configuration conf, NamenodeRole role)
807826
this.haContext = createHAContext();
808827
try {
809828
initializeGenericKeys(conf, nsId, namenodeId);
829+
// TODO 初始化代码
810830
initialize(conf);
811831
try {
812832
haContext.writeLock();
@@ -1416,11 +1436,19 @@ public static NameNode createNameNode(String argv[], Configuration conf)
14161436
LOG.info("createNameNode " + Arrays.asList(argv));
14171437
if (conf == null)
14181438
conf = new HdfsConfiguration();
1439+
/**
1440+
* 操作HDFS集群的时候会传进来如下的参数:
1441+
*
1442+
* hdfs namenode -format
1443+
*
1444+
* hadoop-daemon.sh start namenode
1445+
*/
14191446
StartupOption startOpt = parseArguments(argv);
14201447
if (startOpt == null) {
14211448
printUsage(System.err);
14221449
return null;
14231450
}
1451+
14241452
setStartupOption(conf, startOpt);
14251453

14261454
switch (startOpt) {
@@ -1550,6 +1578,7 @@ public static void main(String argv[]) throws Exception {
15501578

15511579
try {
15521580
StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
1581+
// TODO 创建NameNode 的核心代码
15531582
NameNode namenode = createNameNode(argv, null);
15541583
if (namenode != null) {
15551584
namenode.join();

0 commit comments

Comments
 (0)