• 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 , 启动磁盘资源检查线程等工作)

    具体内容,下一篇介绍

  • 相关阅读:
    [CF707D]Persistent Bookcase_主席树_bitset
    [CF798D]Mike and distribution_贪心
    [LuoguP2164][SHOI2007]交通网络_拓扑排序_概率期望
    [LuoguP3064][USACO12DEC]伊斯坦布尔的帮派Gangs of Istanbull(加强版)_线段树_贪心
    [CF306C]White, Black and White Again_排列组合
    [LuoguP2167][SDOI2009]Bill的挑战_容斥原理/状压dp
    [LuoguP2163][SHOI2007]园丁的烦恼_CDQ分治
    正则字符串插入字符
    [react]
    react 预览pdf 转换
  • 原文地址:https://www.cnblogs.com/niutao/p/12609621.html
Copyright © 2020-2023  润新知