hadoop的机架感知是个什么样的功能呢?如果在HDFS中你的文件副本设置为3,那么这三个副本都是放置在哪里呢?一般情况下,会在本机放置一份,在本机所在的机柜放置一份,在其他机柜放置一份。这样才能保证高可用性,如果都放在一个机柜,万一掉电了,岂不是完蛋了,但是hadoop是怎么能分辨出每个节点所在的机柜位置呢?其实hadoop自身没有这样的功能,hadoop集群分辨某台节点机器是属于哪个机柜并非是自动的感知的,而是需要hadoop的管理者人为的告知hadoop哪台机器属于哪个机柜,这样在hadoop的namenode启动初始化时,会将这些机器与机柜的对应信息保存在内存中,用来作为对接下来所有的HDFS的写块操作分配datanode列表时的选择datanode策略。
脚本文件的作用是,什么呢?
当datanode 向namenode发出heartbeat时,namenode会将每个datanode的IP映射到不同的机柜中。具体过程如下:namenode在每检测到一个节点连接上jobtracker时就会把这个节点的IP地址作为参数传给这个脚本,然后期待这个脚本的返回值返回这台节点所描述的机柜名。而这个脚本内部具体是如何决定节点和机柜的映射hadoop是不关心的。所以,哪台机器属于那个机柜,其实是由写这个脚本的人决定。
这个配置一般在core-site.xml文件的topology.script.file.name配置项来指定脚本位置。这个配置选项的value指定为一个可执行程序,通常为一个脚本,该脚本接受一个参数,输出一个值。接受的参数通常为某台datanode机器的ip地址或者主机名,而输出的值通常为该ip地址对应的datanode所在的机柜。Namenode启动时,会判断该配置选项是否为空,如果非空,则表示已经用机架感知的配置,此时namenode会根据配置寻找该脚本,并在接收到每一个datanode的heartbeat时,将该datanode的ip地址作为参数传给该脚本运行,并将得到的输出作为该datanode所属的机架,保存到内存的一个map中。
<property>
<name>topology.script.file.name</name>
<value>/path/Rack.py</value>
</property>
Rack.py内容如下:
#!/usr/bin/python
#-*-coding:UTF-8 -*-
import sys
rack = {"U-1":"rack1",
"U-2":"rack1",
"U-3":"rack1",
"U-4":"rack1",
"U-5":"rack2",
"U-6":"rack2",
"U-7":"rack2",
"192.168.1.10":"rack1",
"192.168.1.20":"rack1",
"192.168.1.30":"rack1",
"192.168.1.40":"rack1",
"192.168.1.50":"rack2",
"192.168.1.60":"rack2",
"192.168.1.70":"rack2",
}
if __name__=="__main__":
print "/" + rack.get(sys.argv[1],"rack0")