一、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、编写MyRackAware类如下,
package com.phx.hadoop.hdfs.rackaware; import org.apache.hadoop.net.DNSToSwitchMapping; import java.io.FileWriter; import java.util.ArrayList; import java.util.List; public class MyRackAware implements DNSToSwitchMapping { /** * * @param names * @return * Rack: /rack1/002 * 192.168.37.102:50010 (centos002) * Rack: /rack1/003 * 192.168.37.103:50010 (centos003) * Rack: /rack2/004 * 192.168.37.104:50010 (centos004) * Rack: /rack2/005 * 192.168.37.105:50010 (centos005) */ @Override public List<String> resolve(List<String> names) { List<String> list = new ArrayList<String>(); try { FileWriter fw = new FileWriter("/data/hadoop/rackaware.txt",true); for(String str : names){ //输出原来的信息,ip地址(主机名) fw.write(str + " "); // if(str.startsWith("192")){ //192.168.231.202 String ip = str.substring(str.lastIndexOf(".") + 1); if(Integer.parseInt(ip) <= 103) { list.add("/rack1/" + ip); } else{ list.add("/rack2/" + ip); } } else if(str.startsWith("centos")){ String ip = str.substring(6); if (Integer.parseInt(ip) <= 003) { list.add("/rack1/" + ip); } else { list.add("/rack2/" + ip); } } } fw.write(list + " "); fw.close(); } catch (Exception e) { e.printStackTrace(); } return list; } @Override public void reloadCachedMappings() { } @Override public void reloadCachedMappings(List<String> names) { } }
将MyRackAware类打成jar包:MyRackAware.jar
将MyRackAware.jar包分发到所有节点的Hadoop的classpath(${HADOOP_HOME}/share/hadoop/common/lib)下。
2、配置文件core-site.xml中追加配置如下:
<property>
<name>net.topology.node.switch.mapping.impl</name>
<value>com.phx.hadoop.hdfs.rackaware.MyRackAware</value>
</property>
将core-site.xml文件分发到所有Hadoop节点的${HADOOP_HOME}/etc/hadoop
3、重启后,使用命令:hadoop dfsadmin -printTopology 查看配置信息
4.节点间距离计算
有了机架感知,NameNode就可以画出下图所示的datanode网络拓扑图。D1,R1都是交换机,最底层是datanode。则H1的rackid=/D1/R1/H1,H1的parent是R1,R1的是D1。这些rackid信息可以通过topology.script.file.name配置。有了这些rackid信息就可以计算出任意两台datanode之间的距离,得到最优的存放策略,优化整个集群的网络带宽均衡以及数据最优分配。
distance(/D1/R1/H1,/D1/R1/H1)=0 相同的datanode
distance(/D1/R1/H1,/D1/R1/H2)=2 同一rack下的不同datanode
distance(/D1/R1/H1,/D1/R2/H4)=4 同一IDC下的不同datanode
distance(/D1/R1/H1,/D2/R3/H7)=6 不同IDC下的datanode