转载请注明出处:https://blog.csdn.net/l1028386804/article/details/81150863
一、Hadoop机架感知策略
副本节点的选择(机架感知)
1、默认
- 第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。
- 第二个副本在和第一个副本不同机架的随机节点上。
- 第三个副本和第二个副本相同机架,节点随机。
2、hadoop2.7.2策略
- 第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。
- 第二个副本和第一个副本在相同的机架。
- 第三个副本位于不同机架。
二、自定义机架感知步骤
1、创建类实现org.apache.hadoop.net.DNSToSwitchMapping接口
2、在core-site.xml文件中追加如下配置
<property>
<name>net.topology.node.switch.mapping.impl</name>
<value>org.apache.hadoop.net.ScriptBasedMapping</value>
<description> The default implementation of the DNSToSwitchMapping. It
invokes a script specified in net.topology.script.file.name to resolve
node names. If the value for net.topology.script.file.name is not set, the
default value of DEFAULT_RACK is returned for all node names.
</description>
</property>
3、分发core-site.xml
4、编译程序,打成Jar,分发到所有节点的Hadoop的classpath(${HADOOP_HOME/share/hadoop/common/lib})下。
三、自定义机架感知具体实现
1、编写MyDNSToSwitchMapping类如下,
package com.lyz.hadoop.rackaware;
import org.apache.hadoop.net.DNSToSwitchMapping;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: liuyazhuang
* @Date: 2018/7/21 23:18
* @Description: 自定义机架感知策略
*/
public class MyDNSToSwitchMapping implements DNSToSwitchMapping {
/**
* 主机名前缀
*/
private static final String HOST_NAME_PREFIX = "liuyazhuang";
/**
* IP前缀
*/
private static final String IP_PREFIX = "192";
/**
* 传递的是客户端的IP列表,返回机架感知的路径列表
* @param names 客户端的主机名列表或IP列表(这里我们的主机为liuyazhuang121(192.168.209.121)—liuyazhuang125(192.168.209.125))
* @return 机架感知的路径列表
* liuyazhuang121(192.168.209.121)映射为/rack1/121
* liuyazhuang122(192.168.209.122)映射为/rack1/122
* liuyazhuang123(192.168.209.123)映射为/rack2/123
* liuyazhuang124(192.168.209.124)映射为/rack2/124
* liuyazhuang125(192.168.209.125)映射为/rack2/125
*/
public List<String> resolve(List<String> names) {
List<String> list = new ArrayList<String>();
if(names != null && names.size() > 0){
for(String name : names){
int ipSuffix = 0;
//判断是否是以主机名开头,主机名以liuyazhuang121、liuyazhuang122...命名
if(name.startsWith(HOST_NAME_PREFIX)){
//以主机名开头,则取得主机名最后的标识,比如主机名为liuyazhuang121,则取得121
String ip = name.substring(HOST_NAME_PREFIX.length());
ipSuffix = Integer.parseInt(ip);
}else if(name.startsWith(IP_PREFIX)){ //以IP地址命名
//取得IP的最后部分 比如192.168.209.121, 取得121
String ip = name.substring(name.lastIndexOf(".") + 1);
ipSuffix = Integer.parseInt(ip);
}
//ip最后部分小于123,则加入到第一个
if(ipSuffix < 123){
list.add("/rack1/" + ipSuffix);
}else{
list.add("/rack2/" + ipSuffix);
}
}
}
//将机架感知的路径列表写入到/home/liuyazhuang/dns.txt文件中
writeDNSMappingToFile(list);
return list;
}
/**
* 将机架感知的路径列表写入到/home/liuyazhuang/dns.txt文件中
* @param list 将机架感知的路径列表
*/
private void writeDNSMappingToFile(List<String> list) {
try {
//将机架感知的路径列表写入到/home/liuyazhuang/dns.txt文件中
FileOutputStream fos = new FileOutputStream("/home/liuyazhuang/dns.txt");
for(String name : list){
fos.write((name + "\r\n").getBytes());
}
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public void reloadCachedMappings() {
}
public void reloadCachedMappings(List<String> list) {
}
}
将MyDNSToSwitchMapping类打成jar包:MyDNSToSwitchMapping.jar
将MyDNSToSwitchMapping.jar包分发到所有节点的Hadoop的classpath(${HADOOP_HOME}/share/hadoop/common/lib)下。
2、配置文件core-site.xml中追加配置如下:
<property>
<name>net.topology.node.switch.mapping.impl</name>
<value>com.lyz.hadoop.rackaware.MyDNSToSwitchMapping</value>
</property>
将core-site.xml文件分发到所有Hadoop节点的${HADOOP_HOME}/etc/hadoop