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