HDFS------datanode的初始化

来源:互联网 发布:怎么打开企业淘宝店铺 编辑:程序博客网 时间:2024/06/06 13:20

        在conf/start-dfs.sh里可以看到,"$bin"/hadoop-daemons.sh --config $HADOOP_CONF_DIR start datanode $dataStartOpt,这个是用来启动一个datanode的。

因此和namenode一样,先到DataNode的main方法里:

有这样一句:DataNode datanode = createDataNode(args, null);,这行代码就是对用来初始化一个datanode的。

  public static DataNode createDataNode(String args[],
                                 Configuration conf) throws IOException {
    DataNode dn = instantiateDataNode(args, conf);
    runDatanodeDaemon(dn);
    return dn;
  }

可以很清楚地看到共有两部分操作,一个是初始化datanode,一个是开启datanode的后台线程。

一.初始化datanode

略去细节部分,

instantiateDataNode()--->makeInstance()--->new DataNode()--->startDataNode()

主要的初始化工作是在startDataNode方法中进行的。通过分析可以知道:主要的初始化工作分为一下几个步骤:

1.从配置文件中读取一些相关的配置参数,比如nameNodeAddr,socketTimeout,socketWriteTimeout等;

2.通过RPC获取namenode的proxy,并获取namenode的相关信息NamespaceInfo;

          this.namenode = (DatanodeProtocol) RPC.waitForProxy(DatanodeProtocol.class,
                       DatanodeProtocol.versionID,
                       nameNodeAddr,
                       conf);

          NamespaceInfo nsInfo = handshake();

3.检查文件系统状态并进行恢复,同时初始化datanode的内部数据结构FSDataset

      storage.recoverTransitionRead(nsInfo, dataDirs, startOpt);
      // adjust
      this.dnRegistration.setStorageInfo(storage);
      // initialize data node internal structure
      this.data = new FSDataset(storage, conf);

4.寻找一个空闲端口并初始化DataXceiverServer

5.创建DataBlockScanner,创建HttpServer,启动ipc server

二.开启datanode的后台线程

后台线程是通过runDatanodeDaemon方法:

  public static void runDatanodeDaemon(DataNode dn) throws IOException {
    if (dn != null) {
      //register datanode
      dn.register();
      dn.dataNodeThread = new Thread(dn, dnThreadName);
      dn.dataNodeThread.setDaemon(true); // needed for JUnit testing
      dn.dataNodeThread.start();
    }
  }

在开启后台线程之前,先对datanode进行注册,注册信息dnRegistration在第一步初始化的时候已经将相关信息记录到dnRegistration。向namenode注册的作用:是datanode向namenode报告它的一些存储信息,同时namenode会检查datanode的信息并且进行一些更新工作等。

注册成功之后,会启动datanode的后台线程,也就是调用DataNode的run方法(DataNode本身就实现了runnable接口)。

 public void run() {
    LOG.info(dnRegistration + "In DataNode.run, data = " + data);

    // start dataXceiveServer
    dataXceiverServer.start();
        
    while (shouldRun) {
      try {
        startDistributedUpgradeIfNeeded();
        offerService();

      } catch (Exception ex) {
        LOG.error("Exception: " + StringUtils.stringifyException(ex));
        if (shouldRun) {
          try {
            Thread.sleep(5000);
          } catch (InterruptedException ie) {
          }
        }
      }
    }
        
    LOG.info(dnRegistration + ":Finishing DataNode in: "+data);
    shutdown();
  }

可以看到datanode无论发生异常与否都会一直循环运行(除非shutdown), startDistributedUpgradeIfNeeded();是升级用的,offerService是正常工作:

在offerService中主要做三方面的工作:定时向NameNode发送心跳(namenode.sendHeartbeat);报告最新收到的block数据(namenode.blockReceived);报告本地存储的block信息namenode.blockReport。


最后附上DataNode的类图:










原创粉丝点击