注:文中采用的 Hadoop 集群环境为 Hadoop 2.2.0。
最近由于工作需要,对 Hadoop 的机架(rack)策略做了调研。下面记录下调研结果。
背景
首先需要明确的是,机架是硬件,机房里的服务器都放在机架(rack)上。放在不同的 rack 上的机器,有什么区别呢?
- 每个 rack 上的机器连接的是相同的电源,不同的 rack 连接的是不同的电源
这里一个 rack 可以理解成一个「电源插板」。如果某个 rack 断电,则这个 rack 上的机器都会断电;而不同 rack 间的电源是互不影响的。 - rack 内和 rack 间网速不一样:rack 内机器的网速要好于跨 rack 机器间的网速
我的理解是一个 rack 同时相当于一个交换机 switch。Hadoop 2.4.1 的官方文档里提到:Typically large Hadoop clusters are arranged in racks and network traffic between different nodes with in the same rack is much more desirable than network traffic across the racks.
Hadoop 集群启用 rack 策略,主要还是出于数据安全性、集群服务可靠性的考虑。如果文件 block 的 3 个备份存放在不同的 rack 上,则当某个 rack 意外断电时,集群服务仍旧是可用的。
3 备份存放策略
当 Hadoop 集群启用 rack 策略后,数据存放原则如下(参考自 Hadoop 官方文档):
The block replica placement policy is intended to get a tradeoff between minimizing the write cost and maximizing data reliability and availability, and aggregate read bandwidth. When a new block is created, the first replica is placed on the local node, the second one is placed at a different rack, the third one is on a different node at the local rack, and the rest are placed on random nodes with restrictions that no more than one replica is placed at one node and no more than two replicas are placed in the same rack when the number of replicas is less than twice of its rack number.
即,当集群的 rack 数 >=2、每个 rack 的 DataNode 数 >=2(实际应用场景中,一个机架一般不止一台机器)、备份数为 3 时,3 个备份存放在 2 个 rack 的 3 台不同的 DataNode 上。
启用 rack 策略
启用 rack 策略,需要依赖脚本 rack_topology.sh
与数据文件 rack_topology.data
。两个文件的内容分别如下:
#!/bin/bash # rack_topology.sh # Adjust/Add the property "net.topology.script.file.name" to core-site.xml with the "absolute" path the this file. ENSURE the file is "executable". # Supply appropriate rack prefix RACK_PREFIX=default # To test, supply a hostname as script input: if [ $# -gt 0 ]; then HADOOP_CONF=${HADOOP_CONF:-"/home/hadoop/hadoop-2.2.0/etc/hadoop"} CTL_FILE=${CTL_FILE:-"rack_topology.data"} if [ ! -f ${HADOOP_CONF}/${CTL_FILE} ]; then echo -n "/$RACK_PREFIX/rack " exit 0 fi while [ $# -gt 0 ] ; do nodeArg=$1 exec< ${HADOOP_CONF}/${CTL_FILE} result="" while read line ; do ar=( $line ) if [ "${ar[0]}" = "$nodeArg" ] ; then result="${ar[1]}" fi done shift if [ -z "$result" ] ; then echo -n "/$RACK_PREFIX/rack " else echo -n "/$RACK_PREFIX/rack_$result " fi done else echo -n "/$RACK_PREFIX/rack " fi
对脚本文件 rack_topology.sh
的说明如下(参考自Rack Awareness):
The network topology script receives as arguments one or more IP addresses of nodes in the cluster. It returns on stdout a list of rack names, one for each input. The input and output order must be consistent.
192.168.7.190 01 192.168.7.191 01 192.168.7.192 01 192.168.7.193 02 192.168.7.194 02 192.168.7.195 03 192.168.7.195 03
需要注意的是,数据文件的每行记录里使用的应该是 IP 地址,而不是主机名。
启用 rack 策略,过程如下:
- 将启用 rack 策略所需要的脚本
rack_topology.sh
与数据文件rack_topology.data
放在集群所有节点(NameNode & DataNode)上,需要保证 Hadoop 集群用户对脚本rack_topology.sh
的执行权限。 - 停止集群的 HDFS 和 YARN 服务:
stop-dfs.sh
,stop-yarn.sh
。 - 修改
core-site.xml
文件,添加参数topology.script.file.name
用以指定脚本rack_topology.sh
的完整路径(数据文件rack_topology.data
只被脚本rack_topology.sh
直接调用,不需要指定)。topology.script.file.name /home/hadoop/hadoop-2.2.0/etc/hadoop/rack_topology.sh
PS. 经测试,在 Hadoop 2.2.0 上,参数
topology.script.file.name
和参数net.topology.script.file.name
作用相同,均可生效。 - 启动集群的 HDFS 和 YARN 服务:
start-dfs.sh
,start-yarn.sh
。
测试 & 验证
验证思路如下:
- 目前集群数据都是 3 备份存放的。需要验证 3 备份不会只存放在一个 rack 上,也不会存放在 3 个不同的 rack 上,而是恰好存放在 2 个 rack 上。
- 测试需要的机器数目与网络拓扑:
至少 3 个 rack,每个 rack 至少 2 台 DataNode;其中至少一个 rack 需要至少 3 台 DataNode(假设 3 备份可能都存放在这一个 rack 上)。共计 7 台机器。
网络拓扑:a1 a2 a3 属于 rack_a,b1 b2 属于 rack_b,c1 c2 属于 rack_c
测试过程如下:
- 向 HDFS 上添加新文件/目录
hadoop fs -put/-cp
- 检查新文件 block 所在的 rack 和 DataNode
hdfs fsck file_name -files -blocks -locations -racks
经测试、验证后确认,启用 rack 策略后,集群新增文件 block 的存放与官方文档中描述的一致。
其它结论
经过测试、观察,发现其它与 rack 策略相关的一些实验结论:
- 在某个 DataNode 上用
hadoop fs
命令在 HDFS 上写文件,则新生成文件 block 的其中一个备份必然存在于该 DataNode 上 - 如果修改了数据文件
rack_topology.data
,需要重启 HDFS 和 YARN 服务才能生效 - 启用、修改 rack 策略后,
集群上已有数据的存放位置不会发生变动,不考虑 rack 策略。已有 block 的备份原来在哪些 DataNode 上,现在仍然在哪些 DataNode 上。
集群上新数据的存放是考虑 rack 策略的 - 停用 rack 策略后,集群上已有数据的存放位置可能生变动。已有 block 的某些备份存放位置可能发生变化
参考链接: