网络拓扑概念:
在本地网络中,两个节点被称为“彼此近邻”是什么意思?在海量数据处理中,其主要限制因素是节点之间数据的传输速率——带宽很稀缺。这里的想法是将两个节点间的带宽作为距离的衡量标准。
节点距离:两个节点到达最近的共同祖先的距离总和。
例如,假设有数据中心d1机架r1中的节点n1。该节点可以表示为/d1/r1/n1。利用这种标记,这里给出四种距离描述。
Distance(/d1/r1/n1, /d1/r1/n1)=0(同一节点上的进程)
Distance(/d1/r1/n1, /d1/r1/n2)=2(同一机架上的不同节点)
Distance(/d1/r1/n1, /d1/r3/n2)=4(同一数据中心不同机架上的节点)
Distance(/d1/r1/n1, /d2/r4/n2)=6(不同数据中心的节点)
每个节点到父节点的距离为1,n1到r1的距离为1,r1到d1的距离为1,r1下面的n1与r2下面n1的距离就是r1下面n1到d1的距离加上r2下面n1到d1的距离,也就是4因为两个n1共同的祖先为d1.距离越近传输效率越高.
机架感知(副本节点选择)
1)官方ip地址:
http://hadoop.apache.org/docs/r2.7.3/hadoop-project-dist/hadoop-common/RackAwareness.html
http://hadoop.apache.org/docs/r2.7.3/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html#Data_Replication
2)低版本Hadoop副本节点选择
第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。
第二个副本和第一个副本位于不相同机架的随机节点上。
第三个副本和第二个副本位于相同机架,节点随机。
3)Hadoop2.7.2副本节点选择
第一个副本在client所处的节点上。如果客户端在集群外,随机选一个。
第二个副本和第一个副本位于相同机架,随机节点。
第三个副本位于不同机架,随机节点。
为啥2.x比1.x好呢?
假设client在r1下面的n1节点上,按照1.x版本的说法,第一个副本在本节点上,那么距离就是0,第二个副本在不同机架的任意一个节点上,那么就是r2下面的其中一个几点上,那么两者的距离为4,第三个节点也是4总和就是0+4+4=8
而2.x版本第一个副本在r1下面的n1上,第二个副本在相同机架的不同节点上,那么就是r1下面的n2或者n3上,距离与n1为2,第三个节点在不同机架上,距离为4,综合为0+2+4=6
自定义机架
现在定义两个机架,r1,r2现在102,103,104节点,先前集群搭建已经创建过了,现在只需要创建105节点就可以了.
准备工作:
克隆一个虚拟机ip配置为105
主机名修改为hadoop105
java和hadoop环境变量配置好
把文件复制过去后,别忘了把权限改为kxj用户.
scp -r module/ root@hadoop105:/opt/
chown -R kxj:kxj module/
在hadoop102上ssh无密登录到105节点配置好
修改xsync.sh和xcall脚本,把for循环加大1
把集群进行格式化,把每个节点下的hadoop下的data,logs文件夹删掉
修改hadoop102 hadoop/etc/slaves文件添加105节点,然后使用xsync分发
新建项目编写自定义机架类,导入hadoopjar包,之前博客已经说过了,在hdfs的java简单使用里
package com.buba.hdfs;
import org.apache.hadoop.net.DNSToSwitchMapping;
import java.util.ArrayList;
import java.util.List;
public class AutoRack implements DNSToSwitchMapping {
@Override
public List<String> resolve(List<String> ips) {
// ips可能有两种情况 : 1 hadoop102 192.168.1.102
// 0 准备一个返回机架的集合
ArrayList<String> lists = new ArrayList<>();
int ipnumber=0;
//1 获取机架ip
if(ips!=null&&ips.size()>0){
for(String ip : ips){
// hadoop102
if(ip.startsWith("hadoop")){
String ipnum = ip.substring(6);
ipnumber = Integer.parseInt(ipnum);
//192.168.1.102
}else if(ip.startsWith("192")){
int i = ip.lastIndexOf(".");
String ipnum = ip.substring(i + 1);
ipnumber = Integer.parseInt(ipnum);
}
//2 自定义机架感知(把102,103定义为机架1,把104,105定义为机架2)
if(ipnumber < 104){//定义为机架1
lists.add("/rack1/"+ipnumber);
}else{//定义为机架2
lists.add("/rack2/"+ipnumber);
}
}
}
return lists;
}
@Override
public void reloadCachedMappings() {
}
@Override
public void reloadCachedMappings(List<String> list) {
}
}
把这个项目打成jar包,上传到102节点/opt/module/hadoop-2.7.2/share/hadoop/common/lib
分发到别的节点上
注意:
1.这个jar包,必须是jdk1.7版本的,最好跟集群的jdk版本一致为1.7-79版本
2.如果使用的idea打的jar包的话需要删除打好的jar包里的.sf文件不然下面初始化会报错.
修改102节点上 hadoop/etc/core-site.xml 文件配置自定义机架,值为上面自定义机架类的全限定名
<!--自定义机架 -->
<property>
<name>net.topology.node.switch.mapping.impl</name>
<value>com.buba.hdfs.AutoRack</value>
</property>
把这个配置文件进行分发