/**
* 入口
*/
public static void main(String argv[]) throws Exception {
if (DFSUtil.parseHelpArgument(argv, NameNode.USAGE, System.out, true)) {
System.exit(0);
}
try {
StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
NameNode namenode = createNameNode(argv, null);
if (namenode != null) {
namenode.join();
}
} catch (Throwable e) {
LOG.fatal("Exception in namenode join", e);
terminate(1, e);
}
}
public static NameNode createNameNode(String argv[], Configuration conf) throws IOException {
if (conf == null)
conf = new HdfsConfiguration();
StartupOption startOpt = parseArguments(argv);
if (startOpt == null) {
printUsage(System.err);
return null;
}
setStartupOption(conf, startOpt);
if (HAUtil.isHAEnabled(conf, DFSUtil.getNamenodeNameServiceId(conf))/** 檢查當前nameserviec的HA是否可用 **/
&& (startOpt == StartupOption.UPGRADE || startOpt == StartupOption.ROLLBACK || startOpt == StartupOption.FINALIZE)) {
throw new HadoopIllegalArgumentException("Invalid startup option. Cannot perform DFS upgrade with HA enabled.");
}
/**
* 在NameNode federation中,每個NameNode節點是一個nameservice,負責
* 管理一個Namespace和對應的Block pool。整個集羣有一個公共的ClusterID。
* 每一個NameNode上都要執行format
*/
switch (startOpt) {
case FORMAT: {
boolean aborted = format(conf, startOpt.getForceFormat(), startOpt.getInteractiveFormat());
terminate(aborted ? 1 : 0);
return null; // avoid javac warning
}
case GENCLUSTERID: {//系統給你生成一個集羣ID 然後在-clusterid選項中可以使用它
System.err.println("Generating new cluster id:");
System.out.println(NNStorage.newClusterID());
terminate(0);
return null;
}
case FINALIZE: {
boolean aborted = finalize(conf, true);
terminate(aborted ? 1 : 0);
return null; // avoid javac warning
}
case BOOTSTRAPSTANDBY: {
String toolArgs[] = Arrays.copyOfRange(argv, 1, argv.length);
int rc = BootstrapStandby.run(toolArgs, conf);
terminate(rc);
return null; // avoid warning
}
case INITIALIZESHAREDEDITS: {
boolean aborted = initializeSharedEdits(conf, startOpt.getForceFormat(), startOpt.getInteractiveFormat());
terminate(aborted ? 1 : 0);
return null; // avoid warning
}
case BACKUP:
case CHECKPOINT: {
NamenodeRole role = startOpt.toNodeRole();
DefaultMetricsSystem.initialize(role.toString().replace(" ", ""));
return new BackupNode(conf, role);
}
case RECOVER: {
NameNode.doRecovery(startOpt, conf);
return null;
}
default: {
DefaultMetricsSystem.initialize("NameNode");
return new NameNode(conf);
}
}
}
public NameNode(Configuration conf) throws IOException {
this(conf, NamenodeRole.NAMENODE);
}
protected NameNode(Configuration conf, NamenodeRole role) throws IOException {
this.conf = conf;
this.role = role;
/**
* 一般配置Federation模式是需要添加.nsid後綴。這裏是爲了區分不同的NameNode提供不同的nameservice
* 當提供Federation模式時在core-site.xml中<name>fs.defaultFS</name>配置項不需要配置
*
* 如果不配置Federation模式的話是不需要.nsid後綴的 有默認的nameservice
*
* 獲取當前機器namenode的服務地址 如果沒有配置HA功能 一般是不需要添加.nnid後綴的
* 這裏如果配置HA功能 添加.nnid後綴是爲了區別在當前nameservice下哪個是Active節點哪個是StandBy節點
*/
String nsId = getNameServiceId(conf);
String namenodeId = HAUtil.getNameNodeId(conf, nsId);
// 判斷當前是否是ha 即是否是standby
this.haEnabled = HAUtil.isHAEnabled(conf, nsId);
//設置當前節點是否是ha(standby狀態)或active節點(active狀態) namenode有三個類 state三個狀態initial active(active節點即真正工作節點) standby(ha節點)
state = createHAState();
//ha節點是否允許讀操作
this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf);
//設置一個HA上下文 接口
this.haContext = createHAContext();
try {
//設置當前節點信息 把"key.nameserviceId.namenodeId"、"key.nameserviceId"的值賦值給key;
//你會發現你在hdfs-site.xml中配置的"key.nameserviceId.namenodeId"、"key.nameserviceId"
//等參數的值會在後面用到 但是後面使用的時候只是key去獲取;這裏的原因就是這裏把它修改了
initializeGenericKeys(conf, nsId, namenodeId);
initialize(conf);
state.prepareToEnterState(haContext);
state.enterState(haContext);//啓動
} catch (IOException e) {
this.stop();
throw e;
} catch (HadoopIllegalArgumentException e) {
this.stop();
throw e;
}
}
待續