研磨Hadoop源码(四)Hadoop Rack Awareness(机架感知)
2014-07-01 09:58
344 查看
今天跟小伙伴讨论一下hadoop的机架感知机会,又去刨了一下hadoop源码,初略的知道了hadoop机架感知实现
首先我们都知道hadoop默认会将数据存储三份,存储策略为本地一份,同机架内其它某一节点上一份,不同机架的某一节点上一份。这样如果本地数据损坏,节点可以从同一机架内的相邻节点拿到数据,速度肯定比从跨机架节点上拿数据要快;同时,如果整个机架的网络出现异常,也能保证在其它机架的节点上找到数据。那hadoop是怎么知道集群内机器的拓扑关系的呢??
hadoop集群会缓存了每个host与网络拓扑的关系,如何实现缓存可以通过配置项net.topology.node.switch.mapping.impl来定制,但hadoop自己有一个默认实现org.apache.hadoop.net.ScriptBasedMapping,且hadoop所有解析过的域名都会缓存到org.apache.hadoop.net.CachedDNSToSwitchMapping类中,
具体实现:现在hadoop已经自己的所有节点域名names,需要知道所有的域名的拓扑关系,可以调用 org.apache.hadoop.net.CachedDNSToSwitchMapping.resolve(List<String> names)方法进行解析得到,源码如下(具体过程可以参看中文注释)
[java] view
plaincopyprint?
public List<String> resolve(List<String> names) {
// normalize all input names to be in the form of IP addresses
//根据机器域名解析成对应的IP地址
names = NetUtils.normalizeHostNames(names);
List <String> result = new ArrayList<String>(names.size());
if (names.isEmpty()) {
return result;
}
//在缓存中根据所有的IP地址获取拓扑结构,如果获取不到则添加到未缓存的列表
List<String> uncachedHosts = getUncachedHosts(names);
// Resolve the uncached hosts
//调用ScriptBasedMapping的resolve方法解析所有未缓存IP的拓扑
List<String> resolvedHosts = rawMapping.resolve(uncachedHosts);
//cache them
//将解析结果保存到map中,key:IP,value:拓扑结构(/交换机xx/机架xx)
cacheResolvedHosts(uncachedHosts, resolvedHosts);
//now look up the entire list in the cache
//从缓存中获取所有的拓扑列表
return getCachedHosts(names);
}
在这里面,主要的解析逻辑在 rawMapping.resolve(uncachedHosts);中,其具体实现如下:
[java] view
plaincopyprint?
public List<String> resolve(List<String> names) {
List<String> m = new ArrayList<String>(names.size());
if (names.isEmpty()) {
return m;
}
//执行的脚本名称,通过配置项net.topology.script.file.name指定
if (scriptName == null) {
//如果没有配置脚本,则默认所有的主机都处于/default-rack下
for (String name : names) {
m.add(NetworkTopology.DEFAULT_RACK);
}
return m;
}
//运行shell脚本获取脚本执行结果,保存到List中,
//请注意,这里返回的拓扑结构与输入的host顺序是强一致的
String output = runResolveCommand(names);
if (output != null) {
StringTokenizer allSwitchInfo = new StringTokenizer(output);
while (allSwitchInfo.hasMoreTokens()) {
String switchInfo = allSwitchInfo.nextToken();
m.add(switchInfo);
}
if (m.size() != names.size()) {
// invalid number of entries returned by the script
LOG.error("Script " + scriptName + " returned "
+ Integer.toString(m.size()) + " values when "
+ Integer.toString(names.size()) + " were expected.");
return null;
}
} else {
// an error occurred. return null to signify this.
// (exn was already logged in runResolveCommand)
return null;
}
return m;
}
需要注意的是,CachedDNSToSwitchMapping实现了DNSToSwitchMapping接口,因此namenode需要知道集群中某些机器的拓扑结构,只需要调用DNSToSwitchMapping.resolve(List<String> names)即可(实际上它也就是这么做的),有了机器的拓扑结构,只需要比较是否相等则可判断机器是否处于一个rack上
总结,hadoop默认所有机器都处于/default-rack rack上,用户可以通过配置net.topology.script.file.name和net.topology.node.switch.mapping.impl来定制自己的识别策略
(PS:hadoop rack脚本可参考其WIKI提供的一个例子http://wiki.apache.org/hadoop/topology_rack_awareness_scripts,同时可以通过
hdfs fsck /user/filename -files -blocks -locations -racks 查看对应的文件block在哪些rack上)
首先我们都知道hadoop默认会将数据存储三份,存储策略为本地一份,同机架内其它某一节点上一份,不同机架的某一节点上一份。这样如果本地数据损坏,节点可以从同一机架内的相邻节点拿到数据,速度肯定比从跨机架节点上拿数据要快;同时,如果整个机架的网络出现异常,也能保证在其它机架的节点上找到数据。那hadoop是怎么知道集群内机器的拓扑关系的呢??
hadoop集群会缓存了每个host与网络拓扑的关系,如何实现缓存可以通过配置项net.topology.node.switch.mapping.impl来定制,但hadoop自己有一个默认实现org.apache.hadoop.net.ScriptBasedMapping,且hadoop所有解析过的域名都会缓存到org.apache.hadoop.net.CachedDNSToSwitchMapping类中,
具体实现:现在hadoop已经自己的所有节点域名names,需要知道所有的域名的拓扑关系,可以调用 org.apache.hadoop.net.CachedDNSToSwitchMapping.resolve(List<String> names)方法进行解析得到,源码如下(具体过程可以参看中文注释)
[java] view
plaincopyprint?
public List<String> resolve(List<String> names) {
// normalize all input names to be in the form of IP addresses
//根据机器域名解析成对应的IP地址
names = NetUtils.normalizeHostNames(names);
List <String> result = new ArrayList<String>(names.size());
if (names.isEmpty()) {
return result;
}
//在缓存中根据所有的IP地址获取拓扑结构,如果获取不到则添加到未缓存的列表
List<String> uncachedHosts = getUncachedHosts(names);
// Resolve the uncached hosts
//调用ScriptBasedMapping的resolve方法解析所有未缓存IP的拓扑
List<String> resolvedHosts = rawMapping.resolve(uncachedHosts);
//cache them
//将解析结果保存到map中,key:IP,value:拓扑结构(/交换机xx/机架xx)
cacheResolvedHosts(uncachedHosts, resolvedHosts);
//now look up the entire list in the cache
//从缓存中获取所有的拓扑列表
return getCachedHosts(names);
}
在这里面,主要的解析逻辑在 rawMapping.resolve(uncachedHosts);中,其具体实现如下:
[java] view
plaincopyprint?
public List<String> resolve(List<String> names) {
List<String> m = new ArrayList<String>(names.size());
if (names.isEmpty()) {
return m;
}
//执行的脚本名称,通过配置项net.topology.script.file.name指定
if (scriptName == null) {
//如果没有配置脚本,则默认所有的主机都处于/default-rack下
for (String name : names) {
m.add(NetworkTopology.DEFAULT_RACK);
}
return m;
}
//运行shell脚本获取脚本执行结果,保存到List中,
//请注意,这里返回的拓扑结构与输入的host顺序是强一致的
String output = runResolveCommand(names);
if (output != null) {
StringTokenizer allSwitchInfo = new StringTokenizer(output);
while (allSwitchInfo.hasMoreTokens()) {
String switchInfo = allSwitchInfo.nextToken();
m.add(switchInfo);
}
if (m.size() != names.size()) {
// invalid number of entries returned by the script
LOG.error("Script " + scriptName + " returned "
+ Integer.toString(m.size()) + " values when "
+ Integer.toString(names.size()) + " were expected.");
return null;
}
} else {
// an error occurred. return null to signify this.
// (exn was already logged in runResolveCommand)
return null;
}
return m;
}
需要注意的是,CachedDNSToSwitchMapping实现了DNSToSwitchMapping接口,因此namenode需要知道集群中某些机器的拓扑结构,只需要调用DNSToSwitchMapping.resolve(List<String> names)即可(实际上它也就是这么做的),有了机器的拓扑结构,只需要比较是否相等则可判断机器是否处于一个rack上
总结,hadoop默认所有机器都处于/default-rack rack上,用户可以通过配置net.topology.script.file.name和net.topology.node.switch.mapping.impl来定制自己的识别策略
(PS:hadoop rack脚本可参考其WIKI提供的一个例子http://wiki.apache.org/hadoop/topology_rack_awareness_scripts,同时可以通过
hdfs fsck /user/filename -files -blocks -locations -racks 查看对应的文件block在哪些rack上)
相关文章推荐
- 研磨Hadoop源码(四)Hadoop Rack Awareness(机架感知)
- hadoop 配置 机架感知 rack awareness
- Hadoop之block副本放置策略 Rack机架感知源码
- Hadoop学习--机架感知--day05
- Hadoop--Hadoop的机架感知
- Hadoop机架感知配置
- 实现hadoop中的机架感知
- hadoop机架感知
- Hadoop Rack Aware 机架感知
- hadoop性能优化——机架感知
- hadoop-2.7.4-翻译文档-机架感知
- 实现hadoop中的机架感知
- Hadoop Rack Aware 机架感知
- Hadoop配置机架感知(python脚本)
- hadoop机架感知
- 研磨Hadoop源码(一)
- hadoop机架感知与网络拓扑分析:NetworkTopology和DNSToSwitchMapping
- 机架感知(Rack Awareness)机制浅述
- Hadoop之——机架感知配置
- HDFS机架感知功能原理(rack awareness)