1、NameNode啟動流程的初始化操作


 

 閱讀源碼第一步是要編譯源碼;

源碼版本:hadoop2.6+ ~ hadoop2.7 這個范圍均可,改動不是特別大

編譯源碼教程連接:https://www.jianshu.com/p/a66ab0235fb9

https://www.cnblogs.com/hequn/articles/4839689.html

ps. 編譯出錯很常見不要慌 ,只要確保hadoop需要的依賴是正確的(比如protocol),就沒問題!

1、查看源碼NameNode類

在namenode中有一段main函數,說明 我們通過命令啟動namenode的時候,肯定是通過這個main函數來執行的(腳本:hadoop-daemon.sh  、hdfs):

 1 public static void main(String argv[]) throws Exception {
 2     if (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, true)) {
 3       System.out.println("####參數校驗#####");
 4       System.exit(0);
 5       //hadooop namenode -format
 6       //hadoop -datemon.sh start namenode
 7       //hadoop-datemon.sh start nn
 8     }
 9 
10     try {
11       //啟動打印日志
12       StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
13       //TODO 創建NameNode核心代碼
14       NameNode namenode = createNameNode(argv, null);
15       if (namenode != null) {
16         //就是線程的join
17         //會使主線程進入等待池並等待t線程執行完畢后才會被喚醒
18         namenode.join();
19       }
20     } catch (Throwable e) {
21       LOG.error("Failed to start namenode.", e);
22       terminate(1, e);
23     }
24   }

 

 

2、查看核心代碼:createNameNode

NameNode namenode = createNameNode(argv, null);

點擊進入createNameNode(argv , null)函數

顯然我們是啟動namenode,所有都匹配不上,因此會走最后一段

 1 public static NameNode createNameNode(String argv[], Configuration conf)
 2       throws IOException {
 3     LOG.info("createNameNode " + Arrays.asList(argv));
 4     if (conf == null)
 5       conf = new HdfsConfiguration();
 6     StartupOption startOpt = parseArguments(argv);
 7     if (startOpt == null) {
 8       printUsage(System.err);
 9       return null;
10     }
11     //將啟動參數加入到配置中
12     setStartupOption(conf, startOpt);
13     /**
14      * 我們在集群中操作 , 比如 :
15      * hdfs namenode -format
16      * hadoop fs -put XXX /
17      * 正常情況下,是先啟動namenode
18      * hadoop-daemon.sh start namenode
19      * */
20     switch (startOpt) {
21       //格式化
22       case FORMAT: {//hadoop namenode -format
23         boolean aborted = format(conf, startOpt.getForceFormat(),
24                 startOpt.getInteractiveFormat());
25         terminate(aborted ? 1 : 0);
26         return null; // avoid javac warning
27       }
28       // 產生集群ID.
29       case GENCLUSTERID: {
30         System.err.println("Generating new cluster id:");
31         System.out.println(NNStorage.newClusterID());
32         terminate(0);
33         return null;
34       }
35       //定版本
36       case FINALIZE: {
37         System.err.println("Use of the argument '" + StartupOption.FINALIZE +
38                 "' is no longer supported. To finalize an upgrade, start the NN " +
39                 " and then run `hdfs dfsadmin -finalizeUpgrade'");
40         terminate(1);
41         return null; // avoid javac warning
42       }
43       //回滾
44       case ROLLBACK: {
45         boolean aborted = doRollback(conf, true);
46         terminate(aborted ? 1 : 0);
47         return null; // avoid warning
48       }
49       //同步active節點的快照(配置完HA需要運行這個命令同步active節點的快照(配置完HA需要運行這個命令
50       case BOOTSTRAPSTANDBY: {
51         String toolArgs[] = Arrays.copyOfRange(argv, 1, argv.length);
52         int rc = BootstrapStandby.run(toolArgs, conf);
53         terminate(rc);
54         return null; // avoid warning
55       }
56       //向備用節點共享一組edits日志
57       case INITIALIZESHAREDEDITS: {
58         boolean aborted = initializeSharedEdits(conf,
59                 startOpt.getForceFormat(),
60                 startOpt.getInteractiveFormat());
61         terminate(aborted ? 1 : 0);
62         return null; // avoid warning
63       }
64       //啟動冷備或者溫備名字節點
65       case BACKUP:
66       case CHECKPOINT: {
67         NamenodeRole role = startOpt.toNodeRole();
68         DefaultMetricsSystem.initialize(role.toString().replace(" ", ""));
69         return new BackupNode(conf, role);
70       }
71       //恢復損壞的元數據以及文件系統
72       case RECOVER: {
73         NameNode.doRecovery(startOpt, conf);
74         return null;
75       }
76       //檢查配置的正確性
77       case METADATAVERSION: {
78         printMetadataVersion(conf);
79         terminate(0);
80         return null; // avoid javac warning
81       }
82       //以升級的方式啟動
83       case UPGRADEONLY: {
84         DefaultMetricsSystem.initialize("NameNode");
85         new NameNode(conf);
86         terminate(0);
87         return null;
88       }
89       //正常啟動NameNode
90       default: {
91         //初始化metric系統
92         DefaultMetricsSystem.initialize("NameNode");
93         //TODO
94         return new NameNode(conf);
95       }
96     }
97   }

NameNode這個類,里面有一些成員變量,還是很重要,很常見的;比如

 1 //NameNode核心成員變量用來管理元數據(實現對DataNode、Block的管理以及讀寫日志)
 2   protected FSNamesystem namesystem;
 3   //保存配置文件的信息
 4   protected final Configuration conf;
 5   //保存NameNode的角色信息
 6   protected final NamenodeRole role;
 7   //保存NameNode的狀態(HA)
 8   private volatile HAState state;
 9   //是否開啟了高可用(HA)
10   private final boolean haEnabled;
11   //高可用上下文
12   private final HAContext haContext;
13   //NameNode核心成員變量提供RPC服務(提供RPC服務是DataNode和NameNode通信和外部命令管理NameNode的窗口)
14   private NameNodeRpcServer rpcServer;

在這個Namenode的構造參數里面,主要是:

1、對namenode做參數的設置(fs.defaultFS、rpc地址等)

2、初始化

3、根據初始化處理的結果,namenode進入對應的狀態(active、backup、standby)

 1 /**
 2    * 1、對namenode做參數的注冊(fs.defaultFS、rpc地址等)
 3    * 2、初始化
 4    * 3、根據初始化處理的結果,namenode進入對應的狀態(active、backup、standby)
 5    * */
 6   protected NameNode(Configuration conf, NamenodeRole role) 
 7       throws IOException { 
 8     this.conf = conf;
 9     this.role = role;//保存NameNode的角色信息
10     //設置clients訪問nomenode或nameservice的訪問地址  配置項fs.defaultFS:hadoop01:9000
11     setClientNamenodeAddress(conf);
12     String nsId = getNameServiceId(conf);
13     String namenodeId = HAUtil.getNameNodeId(conf, nsId);
14     //ha相關
15     this.haEnabled = HAUtil.isHAEnabled(conf, nsId);
16     //根據用戶設置的啟動參數,確定啟動以后的初始狀態,如果是正常啟動,則全部直接進入Standby狀態
17     state = createHAState(getStartupOption(conf));
18     this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf);
19     //TODO 在創建HA的時候,也啟動了standByNameNode的服務
20     this.haContext = createHAContext();
21 
22 
23 
24     try {
25       //給聯邦模式下准備的,主要是設置聯邦模式下namenode的地址和RPC地址
26       initializeGenericKeys(conf, nsId, namenodeId);
27       //TODO
28       initialize(conf);
29       // HA相關
30       try {
31         haContext.writeLock();
32         state.prepareToEnterState(haContext);
33         state.enterState(haContext);
34       } finally {
35         haContext.writeUnlock();
36       }
37     } catch (IOException e) {
38       this.stop();
39       throw e;
40     } catch (HadoopIllegalArgumentException e) {
41       this.stop();
42       throw e;
43     }
44     this.started.set(true);
45   }

 

 

那么關鍵信息 就是initialize,所以我們接下來重點來看initialize

initialize代碼塊包含了:

1、metrics監控的信息設置
2、hadoop的kerberos的安全認證
3、啟動namendoe的web服務
4、加載元數據
5、創建RPC
6、啟動公共服務startCommonServices (比如:啟動RPC , 啟動磁盤資源檢查線程等工作)

具體內容,下一篇介紹

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM