名字节点启动过程介绍
来源:互联网 发布:蓝牙电话软件 编辑:程序博客网 时间:2024/05/22 13:56
一 启动命令
start-dfs.sh中启动NameNode的部分代码:
# namenodesNAMENODES=$($HADOOP_PREFIX/bin/hdfs getconf -namenodes)echo "Starting namenodes on [$NAMENODES]""$HADOOP_PREFIX/sbin/hadoop-daemons.sh" \ --config "$HADOOP_CONF_DIR" \ --hostnames "$NAMENODES" \ --script "$bin/hdfs" start namenode $nameStartOpt
最终调用了hdfs命令:
if [ "$COMMAND" = "namenode" ] ; then CLASS='org.apache.hadoop.hdfs.server.namenode.NameNode' HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS" …… # run it exec "$JAVA" -Dproc_$COMMAND $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"
二 主函数
首先判断启动参数是否正确,然后注册了一个关闭钩子,调用createNameNode()创建名字节点类,最后掉哟个join()等待子线程关闭。
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.error("Failed to start namenode.", e); terminate(1, e); } }
三 创建名字节点
在createNameNode()函数中首先获取一个Configuration对象,用于加载启动NameNode节点所需的配置参数。然后就是调用parseArguments()函数来获取运行参数。启动参数StartupOption分为以下几类:
- FORMAT : 格式化名字节点,启动HDFS集群前需要对名字节点进行格式化,以建立或重新建立名字节点文件结构。
- GENCLUSTERID : 产生集群ID.
- FINALIZE : 提交上一次升级,目前NameNode名字不再支持”-finalize”命令,建议用户使用’hdfs dfsadmin -finalizeUpgrade’命令。
- ROLLBACK : 从升级系统中回滚到前一个版本,这个参数必须在停止的集群分布式文件系统中使用。
- BOOTSTRAPSTANDBY : 拷贝Active NameNode的最新命名空间到Standby NameNode。
- INITIALIZESHAREDEDITS : 初始化editlog的共享存储空间,并从Active NameNode中拷贝足够的editlog数据,使得Standby NameNode能够顺利启动。
- BACKUP/CHECKPOINT: 启动冷备或者温备名字节点。
- RECOVER : 恢复损坏的元数据以及文件系统。
- METADATAVERSION : 确认配置文件夹存在,并且打印fsimage文件和文件系统的元数据版本。
- UPGRADEONLY : 升级NameNode,升级完成后关闭NameNode。
- REGULAR : 正常启动。
public static NameNode createNameNode(String argv[], Configuration conf) throws IOException { LOG.info("createNameNode " + Arrays.asList(argv)); if (conf == null) conf = new HdfsConfiguration(); // Parse out some generic args into Configuration. GenericOptionsParser hParser = new GenericOptionsParser(conf, argv); argv = hParser.getRemainingArgs(); // Parse the rest, NN specific args. StartupOption startOpt = parseArguments(argv); if (startOpt == null) { printUsage(System.err); return null; } setStartupOption(conf, startOpt); switch (startOpt) { case FORMAT: { boolean aborted = format(conf, startOpt.getForceFormat(), startOpt.getInteractiveFormat()); terminate(aborted ? 1 : 0); return null; // avoid javac warning } case GENCLUSTERID: { System.err.println("Generating new cluster id:"); System.out.println(NNStorage.newClusterID()); terminate(0); return null; } case FINALIZE: { System.err.println("Use of the argument '" + StartupOption.FINALIZE + "' is no longer supported. To finalize an upgrade, start the NN " + " and then run `hdfs dfsadmin -finalizeUpgrade'"); terminate(1); return null; // avoid javac warning } case ROLLBACK: { boolean aborted = doRollback(conf, true); terminate(aborted ? 1 : 0); return null; // avoid 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; } case METADATAVERSION: { printMetadataVersion(conf); terminate(0); return null; // avoid javac warning } case UPGRADEONLY: { DefaultMetricsSystem.initialize("NameNode"); new NameNode(conf); terminate(0); return null; } default: { DefaultMetricsSystem.initialize("NameNode"); return new NameNode(conf); } } }
四 构造名字节点
NameNode的构造函数比较简单,首先解析配置文件,确认当前NameNode是否开启了HA模式,然后对NameNode进行初始化,初始化完成后进入Standby状态,如果出现了异常则停止NameNode服务。
protected NameNode(Configuration conf, NamenodeRole role) throws IOException { this.conf = conf; this.role = role; setClientNamenodeAddress(conf); String nsId = getNameServiceId(conf); String namenodeId = HAUtil.getNameNodeId(conf, nsId); this.haEnabled = HAUtil.isHAEnabled(conf, nsId); state = createHAState(getStartupOption(conf)); this.allowStaleStandbyReads = HAUtil.shouldAllowStandbyReads(conf); this.haContext = createHAContext(); try { initializeGenericKeys(conf, nsId, namenodeId); initialize(conf); try { haContext.writeLock(); state.prepareToEnterState(haContext); state.enterState(haContext); } finally { haContext.writeUnlock(); } } catch (IOException e) { this.stop(); throw e; } catch (HadoopIllegalArgumentException e) { this.stop(); throw e; } this.started.set(true); }
五 初始化名字节点
在initialize内会不仅进行用户的权限验证,加载fsimage,edits到内存;同时也有心跳监控,退役监控,NameNode资源监控,数据块冗余监控等集群监控器;RPC的服务初始化及其重启,HTTP服务的初始化及其启动均在该方法内进行封装实现。
protected void initialize(Configuration conf) throws IOException { if (conf.get(HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS) == null) { String intervals = conf.get(DFS_METRICS_PERCENTILES_INTERVALS_KEY); if (intervals != null) { conf.set(HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS, intervals); } } UserGroupInformation.setConfiguration(conf); //用户登录权限验证 loginAsNameNodeUser(conf); NameNode.initMetrics(conf, this.getRole()); StartupProgressMetrics.register(startupProgress); if (NamenodeRole.NAMENODE == role) { //HttpServer启动 startHttpServer(conf); } this.spanReceiverHost = SpanReceiverHost.get(conf, DFSConfigKeys.DFS_SERVER_HTRACE_PREFIX); //加载元数据,初始化存储目录对象,初始化心跳等管理服务对象,加载命名空间等 loadNamesystem(conf); //创建RPC相关 rpcServer = createRpcServer(conf); if (clientNamenodeAddress == null) { // This is expected for MiniDFSCluster. Set it now using // the RPC server's bind address. clientNamenodeAddress = NetUtils.getHostPortString(rpcServer.getRpcAddress()); LOG.info("Clients are to use " + clientNamenodeAddress + " to access" + " this namenode/service."); } if (NamenodeRole.NAMENODE == role) { httpServer.setNameNodeAddress(getNameNodeAddress()); httpServer.setFSImage(getFSImage()); } //启动停顿检测线程 pauseMonitor = new JvmPauseMonitor(conf); pauseMonitor.start(); metrics.getJvmMetrics().setPauseMonitor(pauseMonitor); //启动NameNode心跳等监控线程;启动RPC,HTTP服务;启动插件等 startCommonServices(conf); }
六 元数据文件加载
NameNode将文件系统的管理委托给了FSNamesystem对象,NameNode会调用FSNamesystem.loadFromDisk()创建FSNamesystem对象,然后将fsimage文件和editlog文件加载到命名空间中。
static FSNamesystem loadFromDisk(Configuration conf) throws IOException { checkConfiguration(conf); FSImage fsImage = new FSImage(conf, FSNamesystem.getNamespaceDirs(conf), FSNamesystem.getNamespaceEditsDirs(conf)); //创建FSNamesystem对象 FSNamesystem namesystem = new FSNamesystem(conf, fsImage, false); StartupOption startOpt = NameNode.getStartupOption(conf); if (startOpt == StartupOption.RECOVER) { namesystem.setSafeMode(SafeModeAction.SAFEMODE_ENTER); } long loadStart = monotonicNow(); try { //加载元数据文件 namesystem.loadFSImage(startOpt); } catch (IOException ioe) { LOG.warn("Encountered exception loading fsimage", ioe); fsImage.close(); throw ioe; } long timeTakenToLoadFSImage = monotonicNow() - loadStart; LOG.info("Finished loading FSImage in " + timeTakenToLoadFSImage + " msecs"); NameNodeMetrics nnMetrics = NameNode.getNameNodeMetrics(); if (nnMetrics != null) { nnMetrics.setFsImageLoadTime((int) timeTakenToLoadFSImage); } return namesystem; }
至此NameNode的启动过程就介绍完了。
1 0
- 名字节点启动过程介绍
- handoop0.20.2:名字节点namenode的启动
- 名字节点(NameNode)基本功能介绍
- Hadoop源码分析笔记(十五):名字节点--启动和停止
- Android 启动过程介绍
- Android 启动过程介绍
- Angular启动过程介绍
- mysql-cluster数据节点启动过程中报错
- Hyperledger Fabric 排序节点启动过程
- AIX开机启动过程介绍
- AIX开机启动过程介绍
- 【Redis】redis介绍-启动过程
- Activity启动过程简要介绍
- 浅析HADOOP启动过程及NN\DN\SNN节点
- 分布式文件系统HDFS名字节点
- 名字节点(NameNode)目录结构
- upstart 和ubuntu启动过程原理介绍
- Linuxupstart和ubuntu启动过程原理介绍
- easyui datagrid 单元格使用进度条
- JavaScript学习笔记 CH.2 SEC.6 循环
- Android开发-自定义View-AndroidStudio(十一)有趣的BUG
- seetaface在嵌入式平台的性能评估以及windows版配置运行
- Java之BufferedReader
- 名字节点启动过程介绍
- 【腾讯云的1001种玩法】如何使用腾讯云做博客
- windows下面调用tracert命令抓包
- c++ list, vector, map, set 区别与用法比较
- Javascript 生成数例的方法们
- 外设IO概述
- 编程思想
- DataTable比List读取的性能高很多;
- Hadoop 2.0 Yarn代码:心跳驱动服务分析