文章目录
  1. 1. Hadoop Rack Awareness
  2. 2. ScriptBasedMapping调用

最近忙的一件事是收到来自同事的需求,探索Hadoop的网络支撑环境。于是我决定先看看Hadoop对于网络拓扑的支持情况。

Hadoop Rack Awareness

在Apache的Hadoop文档中有一段对Rack Awareness的介绍。Hadoop会根据Rack的情况进行容错部署,例如至少将一个备份块放置在不同的Rack中。根据Hadoop文档描述,Hadoop中可以使用Java类以及外部脚本两种方式来指定Host到Rack的映射关系。在这里我选择了使用Script的方式。
Hadoop对Script based的host到rack映射实现在org.apache.hadoop.net.ScriptBasedMapping类中。我们摘录了其中的一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public List<String> resolve(List<String> names) {
List<String> m = new ArrayList<String>(names.size());

if (names.isEmpty()) {
return m;
}

if (scriptName == null) {
for (String name : names) {
m.add(NetworkTopology.DEFAULT_RACK);
}
return m;
}

String output = runResolveCommand(names, scriptName);
if (output != null) {
StringTokenizer allSwitchInfo = new StringTokenizer(output);
while (allSwitchInfo.hasMoreTokens()) {
String switchInfo = allSwitchInfo.nextToken();
m.add(switchInfo);
}

从代码中我们可以看出,如果没有指定外部的映射脚本(net.topology.script.file.name)的话,Hadoop将所有的机器设置在DEFAULT_RACK(/default-rack)下;否则,则将以names作为输入获得映射脚本的输出。Hadoop在调用映射脚本时以IP作为输入,输出/rack$n。
在我的简单集群中,机器一个分成两个Rack。对于Rack的映射可以简单通过IP地址进行映射,从而得到所属的Rack id。我们将映射Shell脚本放置在Hadoop根目录中,在core-site.xml配置net.topology.script.file.name路径。配置更新到集群所有节点。如果在Shell脚本中加入打印信息,我们可以获得Hadoop集群执行过程中的一些调用信息。通过hadoop dfsadmin -report中报告节点信息上我们可以查看到Hadoop集群节点的Rack信息,同时在namenode的log中也可以看到节点的详细注册信息。

ScriptBasedMapping调用

我们可以追究一下ScriptBasedMapping的调用关系。通过追踪Hadoop源码我们可以看到,在DataNodeManager的构造函数中有以下代码:

1
2
3
this.dnsToSwitchMapping = ReflectionUtils.newInstance(
conf.getClass(DFSConfigKeys.NET_TOPOLOGY_NODE_SWITCH_MAPPING_IMPL_KEY,
ScriptBasedMapping.class, DNSToSwitchMapping.class), conf);

yarn的RackResolver中也有一段相同的代码。
而我们看conf.getClass的原型可以知道,这段代码首先获得net.topology.node.switch.mapping.impl对应的类,这个类必须实现 DNSToSwitchMapping接口,如果这个类没有配置,这使用默认类ScriptBasedMapping。下面是Hadoop源码中对getClass的描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/** 
* Get the value of the <code>name</code> property as a <code>Class</code>
* implementing the interface specified by <code>xface</code>.
*
* If no such property is specified, then <code>defaultValue</code> is
* returned.
*
* An exception is thrown if the returned class does not implement the named
* interface.
*
* @param name the class name.
* @param defaultValue default value.
* @param xface the interface implemented by the named class.
* @return property value as a <code>Class</code>,
* or <code>defaultValue</code>.
*/
public <U> Class<? extends U> getClass(String name,
Class<? extends U> defaultValue,
Class<U> xface) {

通过上面的代码分析我们可以得到以下两点:
1、Rackawareness在Hdfs以及Yarn中使用,用于数据及Container的分配指导;
2、Rackawareness首先判断java类实现是否存在,如果不存在再使用ScriptBasedMapping。

文章目录
  1. 1. Hadoop Rack Awareness
  2. 2. ScriptBasedMapping调用