首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 服务器 > 云计算 >

hdfs集群起步——datanode注册(2)

2013-10-22 
hdfs集群启动——datanode注册(2)(转)前面我已经就HDFS集群的启动问题在整体上进行了阐述,而在本文,我将主要

hdfs集群启动——datanode注册(2)

(转)      

前面我已经就HDFS集群的启动问题在整体上进行了阐述,而在本文,我将主要针对DataNode节点在启动的过程中会首先向NameNode节点进行注册这一细节进行深入的讨论。

    先来简单的讲一讲DataNode节点向NameNode节点进行注册的目的吧!DataNode节点向NameNode节点注册,一是告诉NameNode节点自己提供服务的网络地址端口,二是获取NameNode节点对自己的管理与控制。我们说,在一个HDFS集群中有一个NameNode节点和若干DataNode节点(上千台机器,每个机器至少一个节点)。我们不可能给每一个客户端关于所有该集群中的DataNode节点的服务地址,而是让NameNode节点来记住所有的DataNode节点信息,然后客户端通过NameNode节点来获取DataNode节点的信息。当然,真实的情况是,由NameNode节点来收集所有的DataNode的当前工作情况,并以此来负责整个集群的负载均衡与任务的合理安排/调度,即告诉客户端它应该调用那些DataNode节点来获取服务。好吧,现在我们来正式的看看DataNode节点的注册过程吧,实际上主要是NameNode节点是如何处理的?

     DataNode节点调用DatanodeProtocol协议(远程调用接口)来向NameNode节点进行注册,那么NameNode节点是如何处理的呢?当然,在这里我不得不提的是,DataNode向NameNode发送了那些注册信息呢?这些信息包括:hdfs集群起步——datanode注册(2)

其中,name表示DataNode节点提供数据传输/交换的服务地址端口,storageID表示DataNode节点的存储器在整个HDFS集群中的全局编号(当然,这个编号也就由NameNode统一分配),infoPort表示查询DataNode节点当前状态信息的端口号,ipcPort表示DataNode节点提供ClientDatanodeProtocol服务端口号。接下来还是重点看看NameNode节点的处理吧!

      当NameNode节点收到某一个DataNode节点的注册请求之后,它会首先检查DataNode节点所运行的HDFS系统是否和自己是同一个版本号,然后才交给FSNamesystem来处理,源代码:

hdfs集群起步——datanode注册(2)

在FSNamesystem中,会首先判断该DataNode是否被允许被连接到NameNode节点,然而,这是如何进行判断的呢?在配置文件中,有这样两个选项:dfs.hosts和dfs.hosts.exclude,它们的值对应的都是一个文件路径,dfs.hosts指向的文件是一个允许连接到NameNode节点的主机列表,dfs.hosts.exclude指向的文件是一个不允许连接到NameNode节点的主机列表,所以在NameNode节点创建FSNamesystem的时候,会根据配置文件中的选项值从文件中加载这些主机列表,就这么简单。如果这时发现DataNode的storageID为空,会立马给它分配一个全局ID,然后,FSNamesystem会根据DataNode的ip地址把它映射到合适的机架(rack)中,哦,简单的提一下这样做的目的(这个问题我以后会讲到):在大多数情况下,副本系数是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,一个副本存放在同一个机架的另一个节点上,最后一个副本放在不同机架的节点上。这种策略减少了机架间的数据传输,这就提高了数据块写操作的效率。机架的错误远远比节点的错误率低,所以这个策略不会影响到数据的可靠性和可用性。与此同时,因为数据块只放在了两个(不是三个)机架上,所以此策略减少了读取数据块是需要的网络传输总带宽。在这种策略下,副本并不是均匀分布在不同的机架上。三分之二的副本在同一个机架上,其它副本均匀分布在剩下的机架上。这一策略在不损害数据可靠性和读取性能的情况下,尽可能的调高了写的效率。关于机架的概念本文就先谈到这儿,回过头来再看看NameNode接下来的处理吧!另外FSNamesystem还会对该DataNode的描述信息和它对应的storageID做一个映射并保存起来,之后,就把该DataNode节点加入到heartbeats集合中,让HeartbeartMinitor后台线程来实时监测该DataNode节点当前是否还alive。整个注册过程到此也就基本结束了。当然,NameNode节点会把注册结果信息返回给DataNode节点。

    还是整一段源代码先:

  • NavigableMap<String, DatanodeDescriptor> datanodeMap = new TreeMap<String, DatanodeDescriptor>();    
  • Host2NodesMap host2DataNodeMap = new Host2NodesMap();       datanodeMap保存的是注册的storageID与它所在的DataNode节点之间的映射,host2DataNodeMap保存的是注册的host与它上面的DataNode节点之间的映射,请注意这里的host不仅仅指的是一个ip地址,还包含一个端口号,说白了host就是该DataNode节点的数据服务地址。关于注册时的特殊情况及其处理如下:

           1.一台DataNode节点突然宕机了,然后立马恢复重启,NameNode节点也没有及时检测到,那么当这台重启的DataNode节点注册时,就会出现nodeN == nodeS!= null,在这种情况下NameNode节点不会清除与该节点相关的信息,而只是会更新该节点的状态信息,同时重新解析它的ip地址到HDFS集群的网络拓扑图中(这里之所以会重新解析ip地址,是因为在一个DataNode节点重启的过程中唯一可变的就是它所在的网络拓扑结构发生了变化);

           2.一台DataNode节点在突然宕机或者认为stop之后,又马上重启,但是此时该DataNode管理的存储器(逻辑磁盘)并不是之前管理的那一个存储器了,那么该节点注册时就会出现nodeN != null 、nodeS !=nodeN,对于这种情况就相当于是该DataNode节点第一次注册,但是又必须要清除该DataNode节点上一次的注册信息,特别是Block与DataNode之间的映射信息;

           3.当一个DataNode节点由于更换了ip地址,所以它必须要重启并重新向NameNode节点注册,此时该节点注册时就会出现nodeS != null、nodeS!= nodeN(存储器没有变),此时并不需要清除该存储器原来所在的DataNode节点的相关注册信息,主要是Block和DataNode节点之间的映射信息,而只需要更新原来与存储器绑定的DataNode节点的服务器地址信息,当然此时还必须要把新的DataNode节点的ip地址解析到HDFS集群的网络拓扑图中。

  • 热点排行