当前位置: 首页 > 工具软件 > Rack Warden > 使用案例 >

HDFS-机架感知(rack-awareness)

向子安
2023-12-01

HDFS-机架感知

1.机架感知的核心思想

1.1 namenode维护一个Datanode和rack关系的树状网络拓扑数据。
在Namenode上维护一个树状数据结构的NetworkTopology对象,用来映射Rack(机架)、Datanode(数据节点)之间的关系,当Client通过Namenode访问Datanode时,通过一定的策略计算得到访问各个Replication所在Datanode的“距离”。

1.2.副本放置策略
在缺省配置下副本数是3个,通常的策略是:
第一个副本放在和Client相同机架的DataNode里(如果Client不在集群范围,第一个DataNode是随机选取不太满或者不太忙的DataNode);
第二个副本放在与第一个Node不同的机架中的任意dataNode;
第三个副本放在与第二个Node所在机架里不同的Node。

2.HDFS如何知道各个DataNode的网络拓扑情况

机架感知的核心思想是建立在网络拓扑结构的基础之上的,那么Hdfs如何知道各个DataNode的网络拓扑情况的。
在core-site.xml中net.topology.script.file.name定义了一个可执行脚本,用于返回datanode的网络拓扑情况。
遗憾的是,默认为空,也就是在默认情况下,hdfs没有datanode的网络拓扑情况,会认为所有的datanode在相同的默认/default-rack(机架)下面,副本放置时会随机找一个datanode进行存放,而实际的物理网络拓扑很可能不在同一机架上,甚至不在同一集群,对于系统的性能和可靠性会造成影响。

实际应用中需要开启hdfs的机架感知。

3.机架感知核心配置

在core-site.xml中如下配置项是机架感知相关的主要配置信息:

(1)net.topology.impl

默认值:org.apache.hadoop.net.NetworkTopology
描述:网络拓扑的实现类,默认值为:org.apache.hadoop.net.NetworkTopology,表示使用/dc1/rack1格式表示node网络拓扑信息。

(2)net.topology.node.switch.mapping.impl

默认值:org.apache.hadoop.net.ScriptBasedMapping
描述:机架感知网络拓扑实现类,默认情况ScriptBasedMapping,会调用net.topology.script.file.name中配置的脚本文件获取node信息。也可以编写自定义的类,需要实现DNSToSwitchMapping接口。

(3)net.topology.script.file.name

默认值:空
描述:net.topology.node.switch.mapping.impl配置的实现类调用的可执行脚本或者类等文件。

(4)net.topology.table.file.name

默认值:空
描述:当配置的net.topology.node.switch.mapping.impl为org.apache.hadoop.net.TableMapping时才会生效,也就是通过txt文件配置node信息,该属性制定配置信息保存的txt文件。

(5)net.topology.script.number.args

默认值:100
描述:脚本文件最多可配置的node节点信息的个数。

4.机架感知实现方式

4.1 默认配置解析

HDFS默认使用的是内置的 org.apache.hadoop.net.ScriptBasedMapping 类,用来调用外部脚本来解析net.topology.script.file.name字段指定的数据文件。

以下是官方文档给出的bash脚本和数据文件示例:

#!/bin/bash
#mapping.sh
HADOOP_CONF=/etc/hadoop/conf 
 
while [ $# -gt 0 ] ; do
  nodeArg=$1
  exec< ${HADOOP_CONF}/topology.data 
  result="" 
  while read line ; do
    ar=( $line ) 
    if [ "${ar[0]}" = "$nodeArg" ] ; then
      result="${ar[1]}"
    fi
  done 
  shift 
  if [ -z "$result" ] ; then
    echo -n "/default/rack "
  else
    echo -n "$result "
  fi
done 

数据文件dataFile: mapping.data

hadoopdata1.ec.com     /dc1/rack1
hadoopdata1            /dc1/rack1
10.1.1.1               /dc1/rack2

core-site.xml文件相应的字段修改如下:

<property>
    <name>topology.node.switch.mapping.impl</name>
    <value>org.apache.hadoop.net.ScriptBasedMapping</value>
</property>
<property>
    <name>net.topology.script.file.name</name>
    <value>mapping.sh</value>
</property>

4.2 自定义Java类解析

由core-site.xml中的 net.topology.node.switch.mapping.impl字段指定一个自定义实现DNSToSwitchMapping接口类的类:

public class JavaTestBasedMapping implements DNSToSwitchMapping {  
  
    //key:ip value:rack  
    private static ConcurrentHashMap<String,String> cache = new ConcurrentHashMap<String,String>();  
      
    static {  
        //rack0 16  
        cache.put("192.168.5.116", "/ht_dc/rack0");  
        cache.put("192.168.5.117", "/ht_dc/rack0");  
        cache.put("192.168.5.118", "/ht_dc/rack0");  
        cache.put("192.168.5.120", "/ht_dc/rack0");  
        cache.put("192.168.5.121", "/ht_dc/rack0");  
        cache.put("host116", "/ht_dc/rack0");  
        cache.put("host117", "/ht_dc/rack0");  
        cache.put("host118", "/ht_dc/rack0");  
        cache.put("host120", "/ht_dc/rack0");  
        cache.put("host121", "/ht_dc/rack0");  
    }  
      
    @Override  
    public List<String> resolve(List<String> names) {  
        List<String> m = new ArrayList<String>();  
          
        if (names == null || names.size() == 0) {  
            m.add("/default-rack");  
            return m;  
        }  
          
        for (String name : names) {  
            String rack = cache.get(name);  
            if (rack != null) {  
                m.add(rack);  
            }  
        }  
          
        return m;  
    }  
}  

core-site.xml文件相应的字段修改如下:

<property>
    <name>topology.node.switch.mapping.impl</name>
    <value>com.dmp.hadoop.cluster.topology.JavaTestBasedMapping</value>
</property>

4.3 基于配置文件解析

HDFS内置的类org.apache.hadoop.net.StaticMapping实现了对core-site.xml
hadoop.configured.node.mapping配置项定义的主机/rack映射关系的解析,相关配置项的格式为:

<property>
    <name>topology.node.switch.mapping.impl</name>
    <value>org.apache.hadoop.net.StaticMapping</value>
</property>
<property>
    <name>hadoop.configured.node.mapping</name>
    <value>192.168.6.10=/rack1,192.168.6.11=/rack2</value>
</property>

4.4 TableMapping解析

HDFS内置的 org.apache.hadoop.net.TableMapping 类,实现的是对mappingFile的直接解析,mappingFile的格式如下:

192.168.6.10  /rack1
192.168.6.11  /rack2

mappingFile由net.topology.table.file.name配置项定义

5.机架感知扩展

可以做一些工作来优化HDFS的读取流程,因为在很多情况下,HDFS的用户在物理上是跟Datanode节点同一网段的,这样可以视作是同一个Rack,而因为代表用户的ClientMachine没有Rack信息,在NetworkTopology中会被视作与所有Datanode不同Rack,这显然是不合理的,DatanodeManager类中有对非Datanode的节点Rack信息的处理,所以,可以考虑把clientMachine引入NetworkTopology,但不归入Datanode,同样作为叶子节点参与路径长度weight的计算,这样就能够更加科学的对包含数据副本的Datanode进行排序,实现读速度优化的目标

 类似资料: