Hadoop2.x集群动态添加删除数据节点

来源:互联网 发布:浮华饭店结局 知乎 编辑:程序博客网 时间:2024/06/11 20:36

如果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中要换一下文件。整个操作的过程中都不涉及集群的重启~


转自:http://m.blog.csdn.net/blog/can007/9090297

0 0
原创粉丝点击