Hadoop 2.6.0 HDFS Rack Awareness(機(jī)架感知)原理與配置步驟詳解
前言:
??多副本前提下缚态,在訪問Hadoop HDFS集群時推励,訪問速度直接受到Datanode選取策略的影響罢吃。Hadoop HDFS提供了一種Rack Awareness機(jī)制,以便于粗略計算Client到Datanode的訪問開銷蔫慧。本文在Ambari環(huán)境下詳細(xì)分析指郁、介紹兩種配置實現(xiàn)機(jī)架感知的途徑。
(本文基于Hadoop 2.6.0舉例)
一迫肖、Rack Awareness(機(jī)架感知)原理
??關(guān)于Rack Awareness的原理,官方文檔有比較初步的介紹攒驰,簡單來說就是在Namenode上維護(hù)一個樹狀數(shù)據(jù)結(jié)構(gòu)的NetworkTopology對象蟆湖,用來映射Rack、Datanode之間的關(guān)系玻粪,當(dāng)Client通過Namenode訪問Datanode時隅津,通過一定的策略計算得到訪問各個Replication所在Datanode的“距離”。因為我們總是會“認(rèn)為”跨網(wǎng)段劲室、跨Rack訪問是會消耗更多的帶寬資源伦仍、導(dǎo)致更大的訪問延時的。
圖中有兩種節(jié)點很洋,Innernode和Datanode,其中Innernode可以是root節(jié)點充蓝,可以是Datacenter、也可以是Rack喉磁,代表著所有非數(shù)據(jù)實體(switch/router)的節(jié)點谓苟,Innernode的特點是它所有的葉子節(jié)點都是Datanode;Datenode的特點是它沒有子樹或者自己的葉子節(jié)點协怒,它本身只能是葉子節(jié)點涝焙。
在典型的部署工具中,如Ambari孕暇、ClouderaManager仑撞,都集成了Rack(機(jī)架)信息的管理赤兴。實際上,更常見的一種NetworkTopology是這樣的三層結(jié)構(gòu):
那么隧哮,每一個節(jié)點都可以用類似文件路徑的方式來表示它的定位桶良,比如 /Rack1/Dn1、/Dc2/Rack2/Dn4
-
HDFS的寫訪問機(jī)制:
在訪問者client對HDFS進(jìn)行寫訪問時近迁,執(zhí)行如下原則:
副本數(shù) = 1時:
- 首先挑選與client相同Host的Datanode進(jìn)行寫操作艺普;
- 如果沒有,則挑選相同Rack的Datanode鉴竭;
- 如果再沒有歧譬,則隨機(jī)挑選一個Datanode;
副本數(shù) = 2時:
- 第一個副本按照以上原則選取Datanode進(jìn)行寫操作搏存;
- 第二個副本選取一個與第一副本不同Rack的Datanode進(jìn)行寫操作瑰步;
副本數(shù) = 3時:
- 第一、第二副本按照以上原則選取Datanode璧眠;
- 第三個副本選取與第一個副本同Rack的不同Datanode進(jìn)行寫操作缩焦;
副本數(shù) >= 4時:
- 前三個副本按照以上原則選取Datanode;
- 從第四個副本開始责静,隨機(jī)選取Datanode進(jìn)行寫操作袁滥;
每個節(jié)點只保留一份副本,每個Rack不超過兩個副本灾螃。
-
HDFS的讀訪問機(jī)制:
HDFS在讀取文件的時候會首先獲取client的IP题翻,保存在一個clientMachine的字符串對象中,如果是REST調(diào)用腰鬼,則clientMachine就是REST請求發(fā)起者嵌赠,如果是JAVA API訪問,clientMachine就是RPC Client熄赡。
然后DatanodeManager類會以clientMachine為參數(shù)姜挺,到NetworkTopology對象里去檢索計算它到各個保存有replication的Datanode的距離weight,然后根據(jù)weight再進(jìn)行排序彼硫,最后返回給DFSClient進(jìn)行讀取炊豪,從而實現(xiàn)“就近”訪問。
維護(hù)網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)的NetworkTopology類是可以自定義的拧篮,類名在core-site.xml的net.topology.impl字段里定義溜在,如果該字段未定義,則默認(rèn)是類org.apache.hadoop.net.NetworkTopology他托。默認(rèn)類的計算weight的算法是:
- 與clientMachine同Host的Datanode掖肋,weight = 0;
- 與clientMachine不同Host赏参,但是同Rack的Datanode志笼,weight = 2沿盅;
- 與clientMachine不同Rack的Datanode,weight = 4纫溃;
——實際上就是client到目標(biāo)Datanode路徑長度腰涧,如果NetworkTopology類實現(xiàn)了Datacenter,那么對不同Datacenter的Datanode紊浩,weight = 6窖铡;
二、HDFS實現(xiàn)Rack Awareness的技術(shù)途徑
-
Java類直接靜態(tài)解析
由core-site.xml中的 net.topology.node.switch.mapping.impl字段指定一個自定義實現(xiàn)DNSToSwitchMapping接口類的類:
以下是javashooter給出的一個簡單例子:
public class JavaTestBasedMapping implements DNSToSwitchMapping {
//key:ip value:rack
private static ConcurrentHashMap<String,String> cache = new ConcurrentHashMap<String,String>();
static {
//rack0 16
cache.put("192.168.5.116", "/ht_dc/rack0");
cache.put("192.168.5.117", "/ht_dc/rack0");
cache.put("192.168.5.118", "/ht_dc/rack0");
cache.put("192.168.5.120", "/ht_dc/rack0");
cache.put("192.168.5.121", "/ht_dc/rack0");
cache.put("host116", "/ht_dc/rack0");
cache.put("host117", "/ht_dc/rack0");
cache.put("host118", "/ht_dc/rack0");
cache.put("host120", "/ht_dc/rack0");
cache.put("host121", "/ht_dc/rack0");
}
@Override
public List<String> resolve(List<String> names) {
List<String> m = new ArrayList<String>();
if (names == null || names.size() == 0) {
m.add("/default-rack");
return m;
}
for (String name : names) {
String rack = cache.get(name);
if (rack != null) {
m.add(rack);
}
}
return m;
}
}
core-site.xml文件相應(yīng)的字段修改如下:
<property>
<name>topology.node.switch.mapping.impl</name>
<value>com.dmp.hadoop.cluster.topology.JavaTestBasedMapping</value>
</property>
-
Java調(diào)用外部腳本解析mappingFile
HDFS默認(rèn)使用的是內(nèi)置的 org.apache.hadoop.net.ScriptBasedMapping 類坊谁,用來調(diào)用外部腳本來解析net.topology.script.file.name字段指定的數(shù)據(jù)文件费彼。
以下是官方文檔給出的bash腳本和數(shù)據(jù)文件示例(為了強(qiáng)調(diào)是bash腳本,我特意增加了腳本的#-bang):
#!/bin/bash
#mapping.sh
HADOOP_CONF=/etc/hadoop/conf
while [ $# -gt 0 ] ; do
nodeArg=$1
exec< ${HADOOP_CONF}/topology.data
result=""
while read line ; do
ar=( $line )
if [ "${ar[0]}" = "$nodeArg" ] ; then
result="${ar[1]}"
fi
done
shift
if [ -z "$result" ] ; then
echo -n "/default/rack "
else
echo -n "$result "
fi
done
dataFile: mapping.data
hadoopdata1.ec.com /dc1/rack1
hadoopdata1 /dc1/rack1
10.1.1.1 /dc1/rack2
core-site.xml文件相應(yīng)的字段修改如下:
<property>
<name>topology.node.switch.mapping.impl</name>
<value>org.apache.hadoop.net.ScriptBasedMapping</value>
</property>
<property>
<name>net.topology.script.file.name</name>
<value>mapping.sh</value>
</property>
-
基于配置文件的靜態(tài)解析
HDFS內(nèi)置的類org.apache.hadoop.net.StaticMapping實現(xiàn)了對core-site.xml
hadoop.configured.node.mapping配置項定義的主機(jī)/rack映射關(guān)系的解析口芍,相關(guān)配置項的格式為:
<property>
<name>topology.node.switch.mapping.impl</name>
<value>org.apache.hadoop.net.StaticMapping</value>
</property>
<property>
<name>hadoop.configured.node.mapping</name>
<value>192.168.6.10=/rack1,192.168.6.11=/rack2</value>
</property>
-
TableMapping解析
HDFS內(nèi)置的 org.apache.hadoop.net.TableMapping 類箍铲,實現(xiàn)的是對mappingFile的直接解析,mappingFile的格式如下:
192.168.6.10 /rack1
192.168.6.11 /rack2
mappingFile由net.topology.table.file.name配置項定義
幾種方法各有優(yōu)缺點鬓椭,實際運用中可以靈活組合使用颠猴。Ambari和ClouderaManager默認(rèn)使用的都是ScriptBasedMapping類調(diào)用腳本解析。
三小染、利用Rack Awareness機(jī)制對HDFS讀取訪問進(jìn)行優(yōu)化
??有了對以上的機(jī)制了解翘瓮,就可以做一些工作來優(yōu)化HDFS的讀取流程,因為在很多情況下裤翩,HDFS的用戶在物理上是跟Datanode節(jié)點同一網(wǎng)段的春畔,這樣可以視作是同一個Rack,而因為代表用戶的ClientMachine沒有Rack信息岛都,在NetworkTopology中會被視作與所有Datanode不同Rack,這顯然是不合理的振峻,通過閱讀源碼臼疫,發(fā)現(xiàn)DatanodeManager類中有對非Datanode的節(jié)點Rack信息的處理,所以扣孟,可以考慮把clientMachine引入NetworkTopology烫堤,但不歸入Datanode,同樣作為葉子節(jié)點參與路徑長度weight的計算凤价,這樣就能夠更加科學(xué)的對包含數(shù)據(jù)副本的Datanode進(jìn)行排序鸽斟,實現(xiàn)讀速度優(yōu)化的目標(biāo)。這里就不貼源碼獻(xiàn)丑了利诺。
??另外富蓄,還可以對通過修改net.topology.impl改變Hadoop使用的NetworkTopology工具類,自己設(shè)計構(gòu)造網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu)的算法慢逾,實現(xiàn)對具體場景下HDFS文件讀訪問的優(yōu)化立倍。
以上內(nèi)容引用部分均以文字說明或鏈接方式給出灭红。
歡迎轉(zhuǎn)載,轉(zhuǎn)載請聯(lián)系我并注明來源口注。