/**
* 入口
*/
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;
}
}
待续