Hadoop中DataNode的启动过程详解
Hadoop中DataNode的启动过程详解
彭苏云 发表于3年前
Hadoop中DataNode的启动过程详解
  • 发表于 3年前
  • 阅读 122
  • 收藏 0
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

本文的目的在于详细记录2.4.1版本下hadoop的DataNode的启动过程,作此记录,也为以后回过头看DataNode留下方便。本文的思路是结合DataNode的代码,来分析他的启动过程。

说明,限于篇幅,对文章中引用的代码都只留了关键部分。

DataNode同NameNode都一样,是一个java进程,所以从main方法开始,看代码:

public class DataNode extends Configured 
    implements InterDatanodeProtocol, ClientDatanodeProtocol,
    DataNodeMXBean {
  public static void main(String args[]) {
    secureMain(args, null);
  }

  public static void secureMain(String args[], SecureResources resources) {
  	DataNode datanode = createDataNode(args, null, resources);
  }

  public static DataNode createDataNode(String args[], Configuration conf,
      SecureResources resources) throws IOException {
    DataNode dn = instantiateDataNode(args, conf, resources);
    if (dn != null) {
      dn.runDatanodeDaemon();
    }
    return dn;
  }

  public static DataNode instantiateDataNode(String args [], Configuration conf,
      SecureResources resources) throws IOException {
    return makeInstance(dataLocations, conf, resources);
  }

  static DataNode makeInstance(Collection<StorageLocation> dataDirs,
      Configuration conf, SecureResources resources) throws IOException {
    return new DataNode(conf, locations, resources);
  }

  DataNode(final Configuration conf,
           final List<StorageLocation> dataDirs,
           final SecureResources resources) throws IOException {
     startDataNode(conf, dataDirs, resources);
  }

  public void runDatanodeDaemon() throws IOException {
    blockPoolManager.startAll();

    // start dataXceiveServer
    dataXceiverServer.start();
    if (localDataXceiverServer != null) {
      localDataXceiverServer.start();
    }
    ipcServer.start();
    startPlugins(conf);
  }
}



上面的代码跟踪不难,但是最终需要注意两个方法:startDataNode和runDatanodeDaemon方法,前面一个用于初始化DataNode,后面一个启动DataNode的后台线程,这些线程是会伴随DataNode进程一直跑着的。接着,让我们重点研究下方法startDataNode,看代码:


void startDataNode(Configuration conf, 
                     List<StorageLocation> dataDirs,
                    // DatanodeProtocol namenode,
                     SecureResources resources
                     ) throws IOException {
    storage = new DataStorage();
    
    // global DN settings
    registerMXBean();
    initDataXceiver(conf);
    startInfoServer(conf);
    pauseMonitor = new JvmPauseMonitor(conf);
    pauseMonitor.start();

    initIpcServer(conf);
    blockPoolManager = new BlockPoolManager(this);
    blockPoolManager.refreshNamenodes(conf);
  }


registerMXBean这个方法可以忽略,用来注册MBean信息;initDataXceiver这个方法应该来说还是比较重要,实例化的dataXceiverServer用来接受客户端或者其他datanode的数据接收或者发送请求;startInfoServer方法用来启动datanode的web服务器;pauseMonitor用来监控jvm是否有停顿;initIpcServer方法比较重要,用来启动datanode上的rpc服务,主要包括两个服务:ClientDatanodeProtocolPB和InterDatanodeProtocolPB。

然后属于DataNode的重点来了,blockPoolManager对象的实例化,注意一点,2.4.1 这个版本的hadoop已经支持了hadoop Federation的特性,而blockPooolManager就是支撑这个特性来的。现在让我们来看看他里面的东西。还是先上代码吧。

class BlockPoolManager {
  BlockPoolManager(DataNode dn) {
    this.dn = dn;
  }

  void refreshNamenodes(Configuration conf)
      throws IOException {
    synchronized (refreshNamenodesLock) {
      doRefreshNamenodes(newAddressMap);
    }
  }

  private void doRefreshNamenodes(
      Map<String, Map<String, InetSocketAddress>> addrMap) throws IOException {
 synchronized (this) {
		startAll();
	}
  }

  synchronized void startAll() throws IOException {
	for (BPOfferService bpos : offerServices) {
          bpos.start();
     }
  }
}

class BPOfferService {
  void start() {
    for (BPServiceActor actor : bpServices) {
      actor.start();
    }
  }
}

class BPServiceActor implements Runnable {
  void start() {
    if ((bpThread != null) && (bpThread.isAlive())) {
      //Thread is started already
      return;
    }
    bpThread = new Thread(this, formatThreadName());
    bpThread.setDaemon(true); // needed for JUnit testing
    bpThread.start();
  }

  public void run() {
while (true) {
	connectToNNAndHandshake();
     	break;
}

    while (shouldRun()) {
      offerService();   
    }
  }

  private void offerService() throws Exception {
while (shouldRun()) {
	HeartbeatResponse resp = sendHeartBeat();

	List<DatanodeCommand> cmds = blockReport();
}
  }
}


顺着代码往下走,整个思路都会比较清晰了,BPServiceActor这个类做了具体的事情,包括datanode跟namenode的握手,发送心跳和报告块信息,执行namenode发回来的命名。

详细的过程就不啰嗦了。

到这里DataNode的启动过程就搞了一个段落。

 

共有 人打赏支持
粉丝 41
博文 202
码字总数 54255
×
彭苏云
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: