zoukankan      html  css  js  c++  java
  • Hadoop2.x集群动态添加删除数据节点

         如果Hadoop集群已经在运行了,这时可能需要动态的添加新的数据节点到Hadoop系统中去,或者将某个数据节点下线,由于业务的需要,集群是不能重启的,那么具体的DataNode添加、删除步骤是什么样的呢?

    下面以DataNode的上线为例详细说明下如何动态的给HDFS集群新增数据节点(Hadoop2.0版本)。

        首先简单说下几个相关的配置文件。

    (1)由dfs.hosts配置选项指定的白名单文件,当要新上线数据节点的时候,需要把数据节点的名字追加在此文件中;

    (2)由dfs.hosts.exclude配置选项指定的黑名单文件,当要下线数据节点的时候,需要把数据节点的名字追加在此文件中;

        下面开始步骤(假设所有新增数据节点上的Hadoop环境都已经部署完毕):

    Step1:关闭新加入数据节点的防火墙。

    Step2:在两个NameNode节点的hosts文件中加入新增数据节点的hostname。

    Step3:在每个新增数据节点的hosts文件中加入两个NameNode的hostname。

    Step4:在两个NameNode上,打通向新增数据节点无密钥SSH登录的通道。

    Step5:在两个NameNode上的dfs.hosts指定的白名单文件中追加上所有新增的数据节点的hostname,注意是追加!并且,保证在dfs.hosts.exclude指定的黑名单文件中不含有新增的数据节点的hostname。

    Step6:找一个客户端,配置文件和其他节点一致,执行如下刷新命令:

      hdfs dfsadmin -refreshNodes

          (此步也可以在任何其他节点上进行)

    Step7:还是在第6步的客户端上操作,此时需要更改下hdfs-site.xml中的配置选项,将类似于如下的配置选项:

    <property>
             <name>dfs.namenode.rpc-address.mcs.nn0</name>
             <value>namenode0:9000</value>
    </property>
    <property>
          <name>dfs.namenode.rpc-address.mcs.nn1</name>
          <value>namenode1:9000</value>
    </property>

    改为:

    <property>
        <name>dfs.namenode.rpc-address.mcs.nn0</name>
        <value>namenode1:9000</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.mcs.nn1</name>
        <value>namendoe0:9000</value>
    </property>

    Step8:在第7步操作的客户端上重新执行命令:

      hdfs dfsadmin -refreshNodes

    Step9:在数据节点上启动DataNode进程,命令如下:

      hadoop-daemon.sh start datanode

    Step10:查看数据节点进程的情况(通过日志),查看NameNode的web界面。

    Step11:在两个NameNode节点上,更改slaves文件,将要上线的数据节点hostname追加到slaves文件中。

    至于第7步中为什么要更改配置之后在进行第8步的刷新,是因为在Hadoop2.x版本中引入了Federation机制,用户可根据情况定义多组NameNode,每一组有两个NameNode,一个为active,另一个为standby,实现了HA。由于执行刷新命令的节点相当于一个Client,Client将触发当前nameservice中的第一个NameNode执行刷新命令,要使得两个NameNode都刷新,则要更改下配置之后再刷新。具体来说刷新是调用如下方法:

    public int refreshNodes() throws IOException {
    
        int exitCode = -1; 
    
        DistributedFileSystem dfs = getDFS();
    
        dfs.refreshNodes();
    
        exitCode = 0;
    
        return exitCode;
    
      }

        通过获取文件系统对象FileSystem之后,调用FSNamesystem类中的refreshNodes方法:

    void refreshNodes() throws IOException {
    
        checkOperation(OperationCategory.UNCHECKED);
    
        checkSuperuserPrivilege();
    
        getBlockManager().getDatanodeManager().refreshNodes(new HdfsConfiguration());
    
      }

        在检查完相应的操作权限之后,最后由DatanodeManager类来执行具体的刷新实现:

    public void refreshNodes(final Configuration conf) throws IOException {
    
        refreshHostsReader(conf);
    
        namesystem.writeLock();
    
        try {
    
          refreshDatanodes();
    
        } finally {
    
          namesystem.writeUnlock();
    
        }
    
      }

        其中,refreshHostsReader是重新读取dfs.hosts指定的配置文件,将其中的内容加载到内存中,更新白名单列表includes。之后,执行最关键的一步,刷新数据节点列表:

    private void refreshDatanodes() throws IOException {
    
        for(DatanodeDescriptor node : datanodeMap.values()) {
    
          // Check if not include.
    
          if (!inHostsList(node)) {
    
            node.setDisallowed(true); // case 2.
    
          } else {
    
            if (inExcludedHostsList(node)) {
    
              startDecommission(node); // case 3.
    
            } else {
    
              stopDecommission(node); // case 4.
    
            }
    
          }
    
        }
    
      }

        此处的inHostsList方法是当数据节点发来心跳进行注册的时候,判断此节点是否在白名单之中,如果不在的话,就会拒绝该数据节点的注册请求,并抛出异常:

    DisallowedDatanodeException:"Datanode denied communication with namenode: " + nodeID

        至于数据节点的下线,和上述步骤类似,只不过Step5中要换一下文件。真个操作的过程中都不涉及集群的重启~

  • 相关阅读:
    codevs 3657 括号序列
    洛谷P1962 斐波那契数列
    Black Rock shooter
    codevs 2596 售货员的难题
    51Nod-1154 回文串划分
    UVA
    POJ3321[苹果树] 树状数组/线段树 + dfs序
    Hdu 4578 Transformation (线段树 分类分析)
    786B
    438D
  • 原文地址:https://www.cnblogs.com/Scott007/p/3134737.html
Copyright © 2011-2022 走看看