ZooKeeper學習之路 (十)Hadoop的HA集群的機架感知


一、背景

  Hadoop 的設計目的:解決海量大文件的處理問題,主要指大數據的存儲和計算問題,其中, HDFS 解決數據的存儲問題;MapReduce 解決數據的計算問題

  Hadoop 的設計考慮:設計分布式的存儲和計算解決方案架構在廉價的集群之上,所以,服 務器節點出現宕機的情況是常態。數據的安全是重要考慮點。HDFS 的核心設計思路就是對 用戶存進 HDFS 里的所有數據都做冗余備份,以此保證數據的安全

  那么 Hadoop 在設計時考慮到數據的安全,數據文件默認在 HDFS 上存放三份。顯然,這三 份副本肯定不能存儲在同一個服務器節點。那怎么樣的存儲策略能保證數據既安全也能保證 數據的存取高效呢?

  HDFS 分布式文件系統的內部有一個副本存放策略:以默認的副本數=3 為例:

    1、第一個副本塊存本機

    2、第二個副本塊存跟本機同機架內的其他服務器節點

    3、第三個副本塊存不同機架的一個服務器節點上

  好處:

    1、如果本機數據損壞或者丟失,那么客戶端可以從同機架的相鄰節點獲取數據,速度肯定 要比跨機架獲取數據要快。

    2、如果本機所在的機架出現問題,那么之前在存儲的時候沒有把所有副本都放在一個機架 內,這就能保證數據的安全性,此種情況出現,就能保證客戶端也能取到數據

  HDFS 為了降低整體的網絡帶寬消耗和數據讀取延時,HDFS 集群一定會讓客戶端盡量去讀取 近的副本,那么按照以上頭解釋的副本存放策略的結果:

    1、如果在本機有數據,那么直接讀取

    2、如果在跟本機同機架的服務器節點中有該數據塊,則直接讀取

    3、如果該 HDFS 集群跨多個數據中心,那么客戶端也一定會優先讀取本數據中心的數據

  但是 HDFS 是如何確定兩個節點是否是統一節點,如何確定的不同服務器跟客戶端的遠近呢? 答案就是機架感知。!!!!

  在默認情況下,HDFS 集群是沒有機架感知的,也就是說所有服務器節點在同一個默認機架 中。那也就意味着客戶端在上傳數據的時候,HDFS 集群是隨機挑選服務器節點來存儲數據 塊的三個副本的。

  那么假如,datanode1 和 datanode3 在同一個機架 rack1,而 datanode2 在第二個機架 rack2, 那么客戶端上傳一個數據塊 block_001,HDFS 將第一個副本存放在 dfatanode1,第二個副本 存放在 datanode2,那么數據的傳輸已經跨機架一次(從 rack1 到 rack2),然后 HDFS 把第三 個副本存 datanode3,此時數據的傳輸再跨機架一次(從 rack2 到 rack1)。顯然,當 HDFS 需 要處理的數據量比較大的時候,那么沒有配置機架感知就會造成整個集群的網絡帶寬的消耗 非常嚴重。

  下圖是沒有配置機架感知的 HDFS 集群拓撲:

二、配置機架感知

2.1、修改配置文件 core-site.xml

  給 NameNode 節點的 core-site.xml 配置文件增加一項配置:

<property>
  <name>topology.script.file.name</name>
  <value>/home/hadoop/apps/hadoop-2.7.5/etc/hadoop/topology.sh</value>
</property>

  這個配置項的 value 通常是一個執行文件,該執行文件是一個 shell 腳本 topology.sh,

  該腳本 接收一個參數,輸出一個值。

  接收的參數:datanode 節點的 IP 地址,比如:192.168.123.102

  輸出值:datanode 節點所在的機架配置信息,比如:/switch1/rack1

  Namenode 啟動時,會判斷該配置選項是否為空,如果非空,則表示已經啟用機架感知的配 置,此時 namenode 會根據配置尋找該腳本,並在接收到每一個 datanode 的 heartbeat 時,將該 datanode 的 ip 地址作為參數傳給該腳本運行,並將得到的輸出作為該 datanode 所屬的 機架 ID,保存到內存的一個 map 中. 至於腳本的編寫,就需要將真實的網絡拓朴和機架信息了解清楚后,通過該腳本能夠將機器 的 ip 地址和機器名正確的映射到相應的機架上去。一個簡單的實現如下:

topology.sh

#!/bin/bash
HADOOP_CONF=/home/hadoop/apps/hadoop-2.7.5/etc/hadoop while [ $# -gt 0 ] ;
do
 nodeArg=$1
 exec<${HADOOP_CONF}/topology.data
 result=""
 while read line
 do
 ar=( $line )
 if [ "${ar[0]}" = "$nodeArg" ]||[ "${ar[1]}" = "$nodeArg" ]
 then
 result="${ar[2]}"
 fi
 done
 shift
 if [ -z "$result" ]
 then
 echo -n "/default-rack"
 else
 echo -n "$result"
 fi
done

  那么通過閱讀腳本內容知道,我們需要准備一個 topology.data 的文件。topology.data 的內容 如下:

192.168.123.102 hadoop1 /switch1/rack1
192.168.123.103 hadoop2 /switch1/rack1
192.168.123.104 hadoop3 /switch2/rack2
192.168.123.105 hadoop4 /switch2/rack2

  在自己對應的hadoop配置目錄添加這兩個文件,其中 switch 表示交換機,rack 表示機架 需要注意的是,在 Namenode 上,該文件中的節點必須使用 IP,使用主機名無效,而 ResourceManager 上,該文件中的節點必須使用主機名,使用 IP 無效,所以,最好 IP 和主 機名都配上。

   注意:以上兩個文件都需要添加可執行權限

[hadoop@hadoop1 hadoop]$ chmod 777 topology.data topology.sh

2.2、驗證機架感知

  以上配置做好之后,啟動集群,啟動完集群之后,在使用命令:

[hadoop@hadoop1 hadoop]$ hadoop dfsadmin -printTopology
DEPRECATED: Use of this script to execute hdfs command is deprecated.
Instead use the hdfs command for it.

Rack: /switch1/rack1
   192.168.123.102:50010 (hadoop1)
   192.168.123.103:50010 (hadoop2)

Rack: /switch2/rack2
   192.168.123.104:50010 (hadoop3)
   192.168.123.105:50010 (hadoop4)

[hadoop@hadoop1 hadoop]$ 

 

三、補充

3.1、增加 datanode 節點

  增加 datanode 節點,不需要重啟 namenode 非常簡單的做法:在 topology.data 文件中加入新加 datanode 的信息,然后啟動起來就 OK

3.2、節點間距離計算

  有了機架感知,NameNode就可以畫出下圖所示的datanode網絡拓撲圖。

  D1,R1都是交換機, 最底層Hx是 datanode。則 H1 的 rackid=/D1/R1/H1,H1 的 parent 是 R1,R1 的是 D1。這些 rackid 信息可以通過 topology.script.file.name 配置。有了這些 rackid 信息就可以計算出任意兩台 datanode 之間的距離,得到最優的存放策略,優化整個集群的網絡帶寬均衡以及數據最優分配。

distance(/D1/R1/H1,/D1/R1/H1)=0 相同的 datanode
distance(/D1/R1/H1,/D1/R1/H2)=2 同一 rack 下的不同 datanode
distance(/D1/R1/H1,/D1/R2/H4)=4 同一 IDC 下的不同 datanode
distance(/D1/R1/H1,/D2/R3/H7)=6 不同 IDC 下的 datanode

  寫文件時根據策略輸入 dn 節點列表,讀文件時按與client由近到遠距離返回 dn 列表

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM