NameNode启动代码流程

NameNode介绍:

NameNode管理文件系统的命名空间。
  1. 它维护着文件系统树及整棵树内所有的文件和目录。这些信息以两个文件形式永久保存在本地磁盘上:命名空间镜像文件(fsimage)和编辑日志文件(editlog)。
  2. 它管理block块与datanode的映射关系(Namenode启动时候块上报,保存在内存中);
  3. 它能接收cilent的请求,接收datanode的块报告和心跳;
具体实现的类:
  • Namenode类:启动类,管理配置等
  • Namenode server:NameNodeRPCServer(接收和处理所有rpc请求)和NameNodeHttpServer(web)
  • FSNamesystem:负责Namenode的所有逻辑,管理HDFS元数据

fsimage与editlog的作用

fsimage相当于一个快照(checkpoint)保存了最新的元数据检查点,在HDFS启动时加载fsimage的信息,包含了整个HDFS文件系统的所有目录和文件的信息,editlog主要是在NameNode已经启动情况下对HDFS进行的各种更新操作进行记录,HDFS客户端执行所有的写操作都会被记录到editlog中。(类似于redis的RBD+AOF的混合存储方式)
优势:
  1. 可防止fsimage过大或者频繁进行快照
  2. 降低Namedode压力:在Standalone模式下通过Secondary NameNode,HA模式下通过Standby Namenode,将fsimage文件和editolg文件合并成新的fsimage。

启动代码流程图

源码解析

start-dfs.sh脚本是为了启动namenode,定位到Namenode启动类中main方法
public static void main(String argv[]) throws Exception {
    ...
    try {
      StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);
      //创建NN对象
      NameNode namenode = createNameNode(argv, null);
      if (namenode != null) {
        //阻塞作用,让main线程无法结束
        namenode.join();
      }
    } ...
  }
createNameNode是重要的方法,用于构造NN对象
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);
           ...

    boolean aborted = false;
    //根据启动选项执行不同的方法
    switch (startOpt) {
    case FORMAT:
      //初始化
      aborted = format(conf, startOpt.getForceFormat(),startOpt.getInteractiveFormat());
    case GENCLUSTERID:
    case ROLLBACK:
    case BOOTSTRAPSTANDBY:
    case INITIALIZESHAREDEDITS:
    case BACKUP:
    case CHECKPOINT:
    case RECOVER:
    case METADATAVERSION:
    case UPGRADEONLY:
    default:
      DefaultMetricsSystem.initialize("NameNode");
      //构造NN
      return new NameNode(conf);
    }
  }
配置NN后需要先初始化NN,进入format方法
private static boolean format(Configuration conf, boolean force,
      boolean isInteractive) throws IOException {
    ...
    FSImage fsImage = new FSImage(conf, nameDirsToFormat, editDirsToFormat);
    try {
      //构建FSNamesystem用于管理NN信息
      FSNamesystem fsn = new FSNamesystem(conf, fsImage);
      //初始化Journal
      fsImage.getEditLog().initJournalsForWrite();
    }
        ...
    fsImage.format(fsn, clusterId, force);
          ...
    return false;
}
返回createNameNode,new NameNode(conf)构造NN对象
 
 
protected NameNode(Configuration conf, NamenodeRole role)
      throws IOException {
    //配置
    super(conf);
    // 根据配置确认是否开启了HA
    String namenodeId = HAUtil.getNameNodeId(conf, nsId);

    //是否启用ha
    this.haEnabled = HAUtil.isHAEnabled(conf, nsId);

    //非HA -> ACTIVE_STATE
    state = createHAState(getStartupOption(conf));
    //初始化
    initialize(getConf());
    //初始化完成后, Namenode进入Standby状态
    //在这里会开启StandbyCheckpointer里面的checkpointer 线程. 定时合并&处理images文件
    state.prepareToEnterState(haContext);
    state.enterState(haContext);
  }

initialize是重要方法,会初始化httpserver、rpserver,构造FSNamesystem用于管理文件系统 进入initialize(getConf())方法
protected void initialize(Configuration conf) throws IOException {
    //配置

    //构造JvmPauseMonitor对象, 并启动
    pauseMonitor = new JvmPauseMonitor();
    pauseMonitor.init(conf);
    pauseMonitor.start();
    metrics.getJvmMetrics().setPauseMonitor(pauseMonitor);

    //启动HTTP服务
    if (NamenodeRole.NAMENODE == role) {
      startHttpServer(conf);
    }

    // 初始化FSNamesystem
    // NameNode将对文件系统的管理都委托给了FSNamesystem对象,
    // NameNode会调用FSNamesystem.loadFromDisk()创建FSNamesystem对象。
    // FSNamesystem.loadFromDisk()首先调用构造方法构造FSNamesystem对象,
    // 然后将fsimage以及editlog文件加载到命名空间中。
    loadNamesystem(conf);

    //创建RPC服务/创建多个协议/创建serviceRpcServer和clientRpcServer
    rpcServer = createRpcServer(conf);

    //启动公共服务/资源检查/安全模式
    startCommonServices(conf);
    //启动计时器定期将NameNode度量写入日志文件。此行为可由配置禁用。
    startMetricsLogger(conf);
  }
void startCommonServices(Configuration conf, HAContext haContext) throws IOException {
    //NameNode资源检查 通过core-site.xml  hdfs-site.xml两个文件获取元数据存储位置
    //需要检查三个目录,因为这三个目录都涉及到了元数据
    //NameNode的两个目录:存储fsiamge的目录,存储editlog的目录。但是一般情况下,或者默认情况这两个使用的是同一个目录。
    //Journlanode里面有也有存储元数据的目录。高可用的模式了
    //获取到了要检查的目录
    nnResourceChecker = new NameNodeResourceChecker(conf);
    //检查是否有可用资源
    checkAvailableResources();
    //安全模式判断
    //获取正常的block块数x
    long completeBlocksTotal = getCompleteBlocksTotal();
    prog.setTotal(Phase.SAFEMODE, STEP_AWAITING_REPORTED_BLOCKS,
          completeBlocksTotal);
    //启动重要服务
    blockManager.activate(conf, completeBlocksTotal);
  }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值