本文主要讲述如何为CDH集群配置机架感知,通过配置机架感知,提高CDH集群的运行效率。
生产环境的CDH集群通常包含数量庞大的服务器,由于受到机架槽位和交换机网口的限制,通常大型的分布式CDH集群都会跨好几个机架,由多个机架上的机器共同组成一个分布式集群。同机架的机器之间网络传输速度通常都会高于跨机架机器之间的网络传输速度,并且机架之间机器的网络传输速度通常受到上层交换机间网络带宽的限制。
Hadoop作为典型的大数据处理平台,为充分发挥数据本地性的优势,避免数据跨网络传输,优化集群网络带宽资源,最大程度发挥Hadoop的性能,通常会为Hadoop集群配置机架感知,要为Hadoop集群配置机架感知,需要提前知道Hadoop集群的网络拓扑结构。一般来说,配置机架感知就是将逻辑机架和物理机架一一对应。
CDH集群主要节点网络拓扑结构如下:
网络交换机 | 物理机架 | 逻辑机架 | 主机名 | 主机IP |
---|---|---|---|---|
Switch1 | K08 | /k0809/k08 | bigdata[1-7] | 192.***.***.[1-7] |
K09 | /k0809/k09 | bigdata[8-14] | 192.***.***.[8-14] | |
K10 | /k1011/k10 | bigdata[15-22] | 192.***.***.[15-22] | |
K11 | /k1011/k11 | bigdata[23-30] | 192.***.***.[23-30] | |
Switch2 | J03 | /k0809/j03 | bigdata[31-38] | 192.***.***.[31-38] |
J04 | /k0809/j04 | bigdata[39-46] | 192.***.***.[39-46] | |
J05 | /k1011/j05 | bigdata[47-53] | 192.***.***.[47-53] | |
J06 | /k1011/j06 | bigdata[54-60] | 192.***.***.[54-60] |
环境说明:J3/J4的服务器与K8/K9的服务器,可以理解为同一个机柜,他们接入相同的,位于K8/K9堆叠网络设备。J5/J6的服务器与K10/K11的服务器可以理解为同一个机柜,他们接入相同的,位于K10/K11堆叠网络设备。bigdata[34-60]加入了集群,但未启动角色实例。
1.操作系统版本为Redhat7.2
2.CM和CDH版本为5.11.2
3.HDFS已启用HA
机架感知是一种计算不同计算节点之间距离的技术,用以在任务调度过程中尽量减少网络带宽资源的消耗,除此之外,NameNode通过机架感知,可以确定每个DataNode所属的机架ID,优化数据副本存放策略。
副本技术即分布式数据复制技术,是分布式计算的一个重要组成部分。该技术允许数据在多个服务器端共享,一个本地服务器可以存取不同物理地点的远程服务器上的数据,也可以使所有的服务器均持有数据的拷贝。
通过副本技术可以有以下优点:
HDFS最经典的副本存放策略就是“3副本策略”,其使用的是BlockPlacementPolicyDefault策略类,在BlockPlacementPolicyDefault类中的注释具体解释了3个副本的存放位置:
The class is responsible for choosing the desired number of targets for placing block replicas.The replica placement strategy is that if the writer is on a datanode,the 1st replica is placed on the local machine,otherwise a random datanode.The 2nd replica is placed on a datanode that is on a different rack. The 3rd replica is placed on a datanode which is on a different node of the rack as the second replica. |
---|
主要内容如下:第一个副本放在发起写请求的客户端上,如果客户端不在集群内,即不是Datanode,那么随机选取一个Datanode存放;第二个副本放在与第一个副本所在节点的不同机架上;第三个副本放在与第二个副本所在节点的同一机架的不同节点上。
注:如果还有更多的副本,则随机选取节点存放。
默认情况下,机架感知是没有启用的,这时任何一台 Datanode 节点,不管物理上是否属于同一个机架,Namenode 都会默认将他们划分到/default-rack下。
配置机架感知需要人为地告诉Namenode哪台Datanode位于哪个机架下,将真实的网络拓朴和机架信息了解清楚后,通过机架感知脚本将机器的IP地址正确的映射到相应的机架上去,使逻辑机架与物理机架保持一致。
需要注意的是,在Namenode上,必须使用IP,使用主机名无效,而YARN上,必须使用主机名,使用IP无效,所以,建议IP和主机名都配上。配置机架感知后,如果需要新加入Datanode,则需要将Datanode节点信息添加到机架感知脚本中,否则Datanode日志中会有异常信息,且Datanode启动不成功。
1.运行genRack.sh脚本,生成机架信息并写入到/root/RackAware.py文件,脚本内容如下:
root@bigdata60:/root>cat genRack.sh
#!/bin/sh
let n=8
let m=3
for i in {1..60}
do
if [ $i -le 30 ]; then
if [ $i -eq 8 ] || [ $i -eq 15 ] || [ $i -eq 23 ]; then
let n=n+1
fi
if [ $n -le 9 ]; then
echo "\"bigdata$i\":\"/k0809/k0$n\"," >> /root/RackAware.py
else
echo "\"bigdata$i\":\"/k1011/k$n\"," >> /root/RackAware.py
fi
else
if [ $i -eq 39 ] || [ $i -eq 47 ] || [ $i -eq 54 ]; then
let m=m+1
fi
if [ $m -le 4 ]; then
echo "\"bigdata$i\":\"/k0809/j0$m\"," >> /root/RackAware.py
else
echo "\"bigdata$i\":\"/k1011/j0$m\"," >> /root/RackAware.py
fi
fi
done
let n=8
let m=3
for i in {1..60}
do
if [ $i -le 30 ]; then
if [ $i -eq 8 ] || [ $i -eq 15 ] || [ $i -eq 23 ]; then
let n=n+1
fi
if [ $n -le 9 ]; then
echo "\"192.***.***.$i\":\"/k0809/k0$n\"," >> /root/RackAware.py
else
echo "\"192.***.***.$i\":\"/k1011/k$n\"," >> /root/RackAware.py
fi
else
if [ $i -eq 39 ] || [ $i -eq 47 ] || [ $i -eq 54 ]; then
let m=m+1
fi
if [ $m -le 4 ]; then
echo "\"192.***.***.$i\":\"/k0809/j0$m\"," >> /root/RackAware.py
else
echo "\"192.***.***.$i\":\"/k1011/j0$m\"," >> /root/RackAware.py
fi
fi
done
2.编辑RackAware.py脚本,添加python脚本的必要代码,最终脚本内容如下:
root@bigdata60:/root>cat RackAware.py
#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
rack = {"bigdata1":"/k0809/k08",
"bigdata2":"/k0809/k08",
"bigdata3":"/k0809/k08",
"bigdata4":"/k0809/k08",
"bigdata5":"/k0809/k08",
"bigdata6":"/k0809/k08",
"bigdata7":"/k0809/k08",
"bigdata8":"/k0809/k09",
"bigdata9":"/k0809/k09",
"bigdata10":"/k0809/k09",
"bigdata11":"/k0809/k09",
"bigdata12":"/k0809/k09",
"bigdata13":"/k0809/k09",
"bigdata14":"/k0809/k09",
"bigdata15":"/k1011/k10",
"bigdata16":"/k1011/k10",
"bigdata17":"/k1011/k10",
"bigdata18":"/k1011/k10",
"bigdata19":"/k1011/k10",
"bigdata20":"/k1011/k10",
"bigdata21":"/k1011/k10",
"bigdata22":"/k1011/k10",
"bigdata23":"/k1011/k11",
"bigdata24":"/k1011/k11",
"bigdata25":"/k1011/k11",
"bigdata26":"/k1011/k11",
"bigdata27":"/k1011/k11",
"bigdata28":"/k1011/k11",
"bigdata29":"/k1011/k11",
"bigdata30":"/k1011/k11",
"bigdata31":"/k0809/j03",
"bigdata32":"/k0809/j03",
"bigdata33":"/k0809/j03",
"bigdata34":"/k0809/j03",
"bigdata35":"/k0809/j03",
"bigdata36":"/k0809/j03",
"bigdata37":"/k0809/j03",
"bigdata38":"/k0809/j03",
"bigdata39":"/k0809/j04",
"bigdata40":"/k0809/j04",
"bigdata41":"/k0809/j04",
"bigdata42":"/k0809/j04",
"bigdata43":"/k0809/j04",
"bigdata44":"/k0809/j04",
"bigdata45":"/k0809/j04",
"bigdata46":"/k0809/j04",
"bigdata47":"/k1011/j05",
"bigdata48":"/k1011/j05",
"bigdata49":"/k1011/j05",
"bigdata50":"/k1011/j05",
"bigdata51":"/k1011/j05",
"bigdata52":"/k1011/j05",
"bigdata53":"/k1011/j05",
"bigdata54":"/k1011/j06",
"bigdata55":"/k1011/j06",
"bigdata56":"/k1011/j06",
"bigdata57":"/k1011/j06",
"bigdata58":"/k1011/j06",
"bigdata59":"/k1011/j06",
"bigdata60":"/k1011/j06",
"bigdata-job-1":"/bigdata/default",
"bigdata-job-2":"/bigdata/default",
"bigdata-job-3":"/bigdata/default",
"bigdata-mysql-1":"/bigdata/default",
"bigdata-python-1":"/bigdata/default",
"bigdata-python-2":"/bigdata/default",
"cm1":"/bigdata/default",
"cm2":"/bigdata/default",
"192.***.***.1":"/k0809/k08",
"192.***.***.2":"/k0809/k08",
"192.***.***.3":"/k0809/k08",
"192.***.***.4":"/k0809/k08",
"192.***.***.5":"/k0809/k08",
"192.***.***.6":"/k0809/k08",
"192.***.***.7":"/k0809/k08",
"192.***.***.8":"/k0809/k09",
"192.***.***.9":"/k0809/k09",
"192.***.***.10":"/k0809/k09",
"192.***.***.11":"/k0809/k09",
"192.***.***.12":"/k0809/k09",
"192.***.***.13":"/k0809/k09",
"192.***.***.14":"/k0809/k09",
"192.***.***.15":"/k1011/k10",
"192.***.***.16":"/k1011/k10",
"192.***.***.17":"/k1011/k10",
"192.***.***.18":"/k1011/k10",
"192.***.***.19":"/k1011/k10",
"192.***.***.20":"/k1011/k10",
"192.***.***.21":"/k1011/k10",
"192.***.***.22":"/k1011/k10",
"192.***.***.23":"/k1011/k11",
"192.***.***.24":"/k1011/k11",
"192.***.***.25":"/k1011/k11",
"192.***.***.26":"/k1011/k11",
"192.***.***.27":"/k1011/k11",
"192.***.***.28":"/k1011/k11",
"192.***.***.29":"/k1011/k11",
"192.***.***.30":"/k1011/k11",
"192.***.***.31":"/k0809/j03",
"192.***.***.32":"/k0809/j03",
"192.***.***.33":"/k0809/j03",
"192.***.***.34":"/k0809/j03",
"192.***.***.35":"/k0809/j03",
"192.***.***.36":"/k0809/j03",
"192.***.***.37":"/k0809/j03",
"192.***.***.38":"/k0809/j03",
"192.***.***.39":"/k0809/j04",
"192.***.***.40":"/k0809/j04",
"192.***.***.41":"/k0809/j04",
"192.***.***.42":"/k0809/j04",
"192.***.***.43":"/k0809/j04",
"192.***.***.44":"/k0809/j04",
"192.***.***.45":"/k0809/j04",
"192.***.***.46":"/k0809/j04",
"192.***.***.47":"/k1011/j05",
"192.***.***.48":"/k1011/j05",
"192.***.***.49":"/k1011/j05",
"192.***.***.50":"/k1011/j05",
"192.***.***.51":"/k1011/j05",
"192.***.***.52":"/k1011/j05",
"192.***.***.53":"/k1011/j05",
"192.***.***.54":"/k1011/j06",
"192.***.***.55":"/k1011/j06",
"192.***.***.56":"/k1011/j06",
"192.***.***.57":"/k1011/j06",
"192.***.***.58":"/k1011/j06",
"192.***.***.59":"/k1011/j06",
"192.***.***.60":"/k1011/j06",
"192.***.***.23":"/bigdata/default",
"192.***.***.24":"/bigdata/default",
"192.***.***.25":"/bigdata/default",
"192.***.***.16":"/bigdata/default",
"192.***.***.21":"/bigdata/default",
"192.***.***.22":"/bigdata/default",
"192.***.***.156":"/bigdata/default",
"192.***.***.157":"/bigdata/default",
}
if __name__=="__main__":
# 获取机架信息,如果不存在,则返回"/bigdata/default"
print rack.get(sys.argv[1],"/bigdata/default")
3.2.操作步骤
1.将RackAware.py这个机架感知脚本存放在Namenode本次磁盘上,并为脚本赋予执行权限,如果启用了HA,则两个Namenode都需要在本地存放机架感知脚本且存放路径必须相同,避免Namenode发生故障切换导致机架信息不一致。
主Namenode信息如下:
root@bigdata2:/opt/cloudera/parcels/CDH>ll
total 88
drwxr-xr-x 2 root root 4096 Aug 19 2017 bin
drwxr-xr-x 26 root root 4096 Aug 19 2017 etc
drwxr-xr-x 4 root root 52 Aug 19 2017 include
drwxr-xr-x 2 root root 45056 Aug 19 2017 jars
drwxr-xr-x 37 root root 4096 Aug 19 2017 lib
drwxr-xr-x 2 root root 4096 Aug 19 2017 lib64
drwxr-xr-x 3 root root 25 Aug 19 2017 libexec
drwxr-xr-x 2 root root 126 Aug 19 2017 meta
-rwxr-xr-x 1 root root 4241 Jul 20 00:17 RackAware.py
drwxr-xr-x 3 root root 16 Aug 19 2017 share
root@bigdata2:/opt/cloudera/parcels/CDH>pwd
/opt/cloudera/parcels/CDH
root@bigdata2:/opt/cloudera/parcels/CDH>
备Namenode信息如下:
root@bigdata3:/root>cd /opt/cloudera/parcels/CDH
root@bigdata3:/opt/cloudera/parcels/CDH>ll
total 92
drwxr-xr-x 2 root root 4096 Aug 19 2017 bin
drwxr-xr-x 26 root root 4096 Aug 19 2017 etc
drwxr-xr-x 4 root root 52 Aug 19 2017 include
drwxr-xr-x 2 root root 45056 Aug 19 2017 jars
drwxr-xr-x 37 root root 4096 Aug 19 2017 lib
drwxr-xr-x 2 root root 4096 Aug 19 2017 lib64
drwxr-xr-x 3 root root 25 Aug 19 2017 libexec
drwxr-xr-x 2 root root 126 Aug 19 2017 meta
-rwxr-xr-x 1 root root 4241 Jul 20 00:19 RackAware.py
drwxr-xr-x 3 root root 16 Aug 19 2017 share
root@bigdata3:/opt/cloudera/parcels/CDH>
2.在CM管理界面,为所有主机分配逻辑机架,与机架感知脚本配置的机架信息保持一致
3.登录CM管理界面,在HDFS配置项搜索“topology”,指定机架感知脚本在Namenode节点上的存放路径,保存更改后重启HDFS
1.启用机架感知前,使用HDFS命令打印CDH集群机架信息如下:
root@bigdata1:/data5>sudo -u hdfs hdfs dfsadmin -printTopology
Rack: /default
192.***.***.10:50010 (bigdata10)
192.***.***.11:50010 (bigdata11)
192.***.***.12:50010 (bigdata12)
192.***.***.13:50010 (bigdata13)
192.***.***.14:50010 (bigdata14)
192.***.***.15:50010 (bigdata15)
192.***.***.16:50010 (bigdata16)
192.***.***.17:50010 (bigdata17)
192.***.***.18:50010 (bigdata18)
192.***.***.19:50010 (bigdata19)
192.***.***.20:50010 (bigdata20)
192.***.***.21:50010 (bigdata21)
192.***.***.22:50010 (bigdata22)
192.***.***.23:50010 (bigdata23)
192.***.***.24:50010 (bigdata24)
192.***.***.25:50010 (bigdata25)
192.***.***.26:50010 (bigdata26)
192.***.***.27:50010 (bigdata27)
192.***.***.28:50010 (bigdata28)
192.***.***.29:50010 (bigdata29)
192.***.***.30:50010 (bigdata30)
192.***.***.31:50010 (bigdata31)
192.***.***.32:50010 (bigdata32)
192.***.***.33:50010 (bigdata33)
192.***.***.4:50010 (bigdata4)
192.***.***.5:50010 (bigdata5)
192.***.***.6:50010 (bigdata6)
192.***.***.7:50010 (bigdata7)
192.***.***.8:50010 (bigdata8)
192.***.***.9:50010 (bigdata9)
Rack: /default-rack
192.***.***.34:50010 (bigdata34)
192.***.***.35:50010 (bigdata35)
192.***.***.36:50010 (bigdata36)
192.***.***.37:50010 (bigdata37)
192.***.***.38:50010 (bigdata38)
192.***.***.39:50010 (bigdata39)
192.***.***.40:50010 (bigdata40)
192.***.***.41:50010 (bigdata41)
192.***.***.42:50010 (bigdata42)
192.***.***.43:50010 (bigdata43)
192.***.***.44:50010 (bigdata44)
192.***.***.45:50010 (bigdata45)
192.***.***.46:50010 (bigdata46)
192.***.***.47:50010 (bigdata47)
192.***.***.48:50010 (bigdata48)
192.***.***.49:50010 (bigdata49)
192.***.***.50:50010 (bigdata50)
192.***.***.51:50010 (bigdata51)
192.***.***.52:50010 (bigdata52)
192.***.***.53:50010 (bigdata53)
192.***.***.54:50010 (bigdata54)
192.***.***.55:50010 (bigdata55)
192.***.***.56:50010 (bigdata56)
192.***.***.57:50010 (bigdata57)
192.***.***.58:50010 (bigdata58)
192.***.***.59:50010 (bigdata59)
192.***.***.60:50010 (bigdata60)
root@bigdata1:/data5>
可以看到,集群已启动的节点都划分到/default机架下,未启动的节点(bigdata[34-60])都划分到了/default-rack机架下。
2.启用机架感知后,使用HDFS命令打印CDH集群机架信息如下:
root@bigdata2:/var/lib/zookeeper>sudo -u hdfs hdfs dfsadmin -printTopology
Rack: /default-rack
192.***.***.34:50010 (bigdata34)
192.***.***.35:50010 (bigdata35)
192.***.***.36:50010 (bigdata36)
192.***.***.37:50010 (bigdata37)
192.***.***.38:50010 (bigdata38)
192.***.***.39:50010 (bigdata39)
192.***.***.40:50010 (bigdata40)
192.***.***.41:50010 (bigdata41)
192.***.***.42:50010 (bigdata42)
192.***.***.43:50010 (bigdata43)
192.***.***.44:50010 (bigdata44)
192.***.***.45:50010 (bigdata45)
192.***.***.46:50010 (bigdata46)
192.***.***.47:50010 (bigdata47)
192.***.***.48:50010 (bigdata48)
192.***.***.49:50010 (bigdata49)
192.***.***.50:50010 (bigdata50)
192.***.***.51:50010 (bigdata51)
192.***.***.52:50010 (bigdata52)
192.***.***.53:50010 (bigdata53)
192.***.***.54:50010 (bigdata54)
192.***.***.55:50010 (bigdata55)
192.***.***.56:50010 (bigdata56)
192.***.***.57:50010 (bigdata57)
192.***.***.58:50010 (bigdata58)
192.***.***.59:50010 (bigdata59)
192.***.***.60:50010 (bigdata60)
Rack: /k0809/j03
192.***.***.31:50010 (bigdata31)
192.***.***.32:50010 (bigdata32)
192.***.***.33:50010 (bigdata33)
Rack: /k0809/k08
192.***.***.4:50010 (bigdata4)
192.***.***.5:50010 (bigdata5)
192.***.***.6:50010 (bigdata6)
192.***.***.7:50010 (bigdata7)
Rack: /k0809/k09
192.***.***.10:50010 (bigdata10)
192.***.***.11:50010 (bigdata11)
192.***.***.12:50010 (bigdata12)
192.***.***.13:50010 (bigdata13)
192.***.***.14:50010 (bigdata14)
192.***.***.8:50010 (bigdata8)
192.***.***.9:50010 (bigdata9)
Rack: /k1011/k10
192.***.***.15:50010 (bigdata15)
192.***.***.16:50010 (bigdata16)
192.***.***.17:50010 (bigdata17)
192.***.***.18:50010 (bigdata18)
192.***.***.19:50010 (bigdata19)
192.***.***.20:50010 (bigdata20)
192.***.***.21:50010 (bigdata21)
192.***.***.22:50010 (bigdata22)
Rack: /k1011/k11
192.***.***.23:50010 (bigdata23)
192.***.***.24:50010 (bigdata24)
192.***.***.25:50010 (bigdata25)
192.***.***.26:50010 (bigdata26)
192.***.***.27:50010 (bigdata27)
192.***.***.28:50010 (bigdata28)
192.***.***.29:50010 (bigdata29)
192.***.***.30:50010 (bigdata30)
root@bigdata2:/var/lib/zookeeper>
这里需要特别说明一下:机架感知脚本已经为bigdata[34-60]配置了映射关系,但是由于bigdata[34-60]加入集群后,其上部署的角色实例尚未启动,Namenode默认将其划分到了/default-rack机架下,一旦bigdata[34-60]启动其上部署的角色实例,那么Namenode会依据机架感知脚本配置的信息为其划分机架。集群已启动的节点机架信息与脚本配置一致。
1.配置机架感知需要编写机架感知脚本并赋予执行权限,NameNode通过机架感知脚本,可以确定每个DataNode所属的机架ID,通过CM管理界面为所有节点分配逻辑机架,通常逻辑机架和物理机架一一对应,如果配置逻辑机架包含两层(交换机和机架),那么建议所有逻辑机架都要配置两层,不能出现主机配置逻辑机架层数不一致的情况,否则CM会有告警提示。假如物理机上做了虚拟化,那么虚拟化这一层也要配置到逻辑机架中。
2.如果集群启用了HA,则两个Namenode节点需要在本地磁盘的相同路径下存放机架感知脚本。通过CM管理界面,配置HDFS的“topology”参数,指定机架感知脚本存放路径。
3.机架感知脚本不能存放在“/etc/hadoop/conf.cloudera.hdfs/”目录下,否则重新部署HDFS客户端配置时,会将机架感知脚本清除。现已将机架感知脚本存放在“/opt/cloudera/parcels/CDH/”目录下。
4.机架感知脚本也可以参考官方给的实例,使用Shell脚本编写,具体参看:https://wiki.apache.org/hadoop/topology_rack_awareness_scripts
5.配置机架感知后,使用SparkSQL可能会出现如下警告信息:
18/07/20 09:31:32 WARN net.ScriptBasedMapping: Exception running /opt/cloudera/parcels/CDH/RackAware.py 192.***.***.35
java.io.IOException: Cannot run program "/opt/cloudera/parcels/CDH/RackAware.py" (in directory "/home/iotcdh"): error=2, 没有那个文件或目录
如果出现该问题,将机架感知脚本拷贝到部署了Spark角色实例的所有节点上,与Namenode存放机架感知脚本的路径保持一致。
参考文章:
https://www.ibm.com/developerworks/cn/data/library/bd-1505-hdfs-uilbps-optimize/index.html
https://blog.csdn.net/androidlushangderen/article/details/51178253
https://wiki.apache.org/hadoop/topology_rack_awareness_script