[Hadoop]HDFS機架感知策略
HDFS NameNode對文件塊復制相關所有事物負責,它周期性接受來自於DataNode的HeartBeat和BlockReport信息,HDFS文件塊副本的放置對於系統整體的可靠性和性能有關鍵性影響。
一個簡單但非優化的副本放置策略是,把副本分別放在不同機架,甚至不同IDC。這樣可以防止整個機架、甚至整個IDC崩潰帶來的錯誤,但是這樣文件寫必須在多個機架之間、甚至IDC之間傳輸,增加了副本寫的代價。
在缺省配置下副本數是3個,通常的策略是:第一個副本放在和Client相同機架的Node裏(如果Client不在集群範圍,第一個Node是隨機選取不太滿或者不太忙的Node);第二個副本放在與第一個Node不同的機架中的Node;第三個副本放在與第二個Node所在機架裏不同的Node。
Hadoop的副本放置策略在可靠性(副本在不同機架)和帶寬(只需跨越一個機架)中做了一個很好的平衡。
但是,HDFS如何知道各個DataNode的網絡拓撲情況呢?它的機架感知功能需要 topology.script.file.name 屬性定義的可執行文件(或者腳本)來實現,文件提供了NodeIP對應RackID的翻譯。如果 topology.script.file.name 沒有設定,則每個IP都會翻譯成/default-rack。
默認情況下,Hadoop機架感知是沒有啟用的,需要在NameNode機器的hadoop-site.xml裏配置一個選項,例如:
<property> <name>topology.script.file.name</name> <value>/path/to/script</value> </property>
這個配置選項的value指定為一個可執行程序,通常為一個腳本,該腳本接受一個參數,輸出一個值。接受的參數通常為datanode機器的ip地址,而輸出的值通常為該ip地址對應的datanode所在的rackID,例如”/rack1”。Namenode啟動時,會判斷該配置選項是否為空,如果非空,則表示已經啟用機架感知的配置,此時namenode會根據配置尋找該腳本,並在接收到每一個datanode的heartbeat時,將該datanode的ip地址作為參數傳給該腳本運行,並將得到的輸出作為該datanode所屬的機架,保存到內存的一個map中。
至於腳本的編寫,就需要將真實的網絡拓樸和機架信息了解清楚後,通過該腳本能夠將機器的ip地址正確的映射到相應的機架上去。Hadoop官方給出的腳本:http://wiki.apache.org/hadoop/topology_rack_awareness_scripts
以下分別是沒有配置機架感知信息和配置機架感知信息的hadoop HDFS進行數據上傳時的測試結果。
當沒有配置機架信息時,所有的機器hadoop都默認在同一個默認的機架下,名為 “/default-rack”,這種情況下,任何一臺datanode機器,不管物理上是否屬於同一個機架,都會被認為是在同一個機架下,此時,就很容易出現之前提到的增添機架間網絡負載的情況。在沒有機架信息的情況下,namenode默認將所有的slaves機器全部默認為在/default-rack下,此時寫block時,三個datanode機器的選擇完全是隨機的。
當配置了機架感知信息以後,hadoop在選擇三個datanode時,就會進行相應的判斷:
1. 如果上傳本機不是一個datanode,而是一個客戶端,那麽就從所有slave機器中隨機選擇一臺datanode作為第一個塊的寫入機器(datanode1)。而此時如果上傳機器本身就是一個datanode,那麽就將該datanode本身作為第一個塊寫入機器(datanode1)。
2. 隨後在datanode1所屬的機架以外的另外的機架上,隨機的選擇一臺,作為第二個block的寫入datanode機器(datanode2)。
3. 在寫第三個block前,先判斷是否前兩個datanode是否是在同一個機架上,如果是在同一個機架,那麽就嘗試在另外一個機架上選擇第三個datanode作為寫入機器(datanode3)。而如果datanode1和datanode2沒有在同一個機架上,則在datanode2所在的機架上選擇一臺datanode作為datanode3。
4. 得到3個datanode的列表以後,從namenode返回該列表到DFSClient之前,會在namenode端首先根據該寫入客戶端跟datanode列表中每個datanode之間的“距離”由近到遠進行一個排序,客戶端根據這個順序有近到遠的進行數據塊的寫入。
5. 當根據“距離”排好序的datanode節點列表返回給DFSClient以後,DFSClient便會創建Block OutputStream,並向這次block寫入pipeline中的第一個節點(最近的節點)開始寫入block數據。
6. 寫完第一個block以後,依次按照datanode列表中的次遠的node進行寫入,直到最後一個block寫入成功,DFSClient返回成功,該block寫入操作結束。
通過以上策略,namenode在選擇數據塊的寫入datanode列表時,就充分考慮到了將block副本分散在不同機架下,並同時盡量地避免了之前描述的網絡開銷。
作者:GodHehe
鏈接:https://www.jianshu.com/p/372d25352d3a
[Hadoop]HDFS機架感知策略