什么是机架感知?
机架感知简单的讲 就是告诉集群各个从节点所在的机架。方便集群更有效率的存储数据、利用资源。
默认的副本存储策略:
首选在本地机架的一个node存放副本,另一个副本在本地机架的另一个不同节点。
最后一个副本在不同机架的不同节点上。
怎么告诉集群?
Hadoop 并没有那么智能,知道各个从节点所在的机架。
主要管理员手动的去配置。如果不配置,它会生成一个 default-rack.xml ,认为所有的 DataNode 的节点在一个机架上。
如何配置呢?
下面我们将以 3 台从节点为例:
它们分别是:s102 s103 s104
- 自定义类实现 DNSToSwitchMapping,重写 resolve() 方法;打为 jar 包,并复制到 NameNode 节点的 /soft/hadoop/shared/hadoop/common/lib 目录下
/** * 机架感知类 */ public class MyRackAware implements DNSToSwitchMapping { /** * 根据需求,将不同的主机划分到不同的机架上 * @param names 数据节点主机的集合 * @return 机架感知的集合 */ public List<String> resolve(List<String> names) { List<String> list = new ArrayList<String>(); try { //将原始信息输出到目录,方便查看 FileWriter fw = new FileWriter("/home/centos/rackaware.txt"); for (String host : names) { //将输入的原始host写入文件 fw.append(host+"/r/n"); //进行原始的host进行分机架 // IP形式 if (host.startsWith("192")) { String ipEnd = host.substring(host.lastIndexOf(".") + 1); if (Integer.parseInt(ipEnd) <= 103) { //s102,s103 在一个机架 list.add("/rack1/" + ipEnd); } else { //s104 在一个机架 list.add("/rack2/" + ipEnd); } } //主机名形式 else if (host.startsWith("s")) { String ipEnd = host.substring(1); if (Integer.parseInt(ipEnd) <= 103) { //s102,s103 在一个机架 list.add("/rack1/" + ipEnd); } else { //s104 在一个机架 list.add("/rack2/" + ipEnd); } } } fw.close(); } catch (IOException e) { e.printStackTrace(); } return list; } public void reloadCachedMappings() { } public void reloadCachedMappings(List<String> names) { } }
- 配置 core-site.xml 的 net.topology.node.switch.mapping.impl 属性,并分发到各个节点
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://192.168.37.101/</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/home/centos/hadoop</value> </property> <property> <name>net.topology.node.switch.mapping.impl</name> <value>com.fresher.hdfs.rackaware.MyRackAware</value> </property> </configuration>
- 重启集群即可