好程式設計師大資料學習路線分享Hadoop機架感知
好程式設計師 大資料學習路線分享Hadoop機架感知 , 1.背景 : Hadoop在設計時考慮到資料的安全與高效,資料檔案預設在HDFS上存放三份,儲存策略為本地一份,同機架內其它某一節點上一份,不同機架的某一節點上一份。這樣如果本地資料損壞,節點可以從同一機架內的相鄰節點拿到資料,速度肯定比從跨機架節點上拿資料要快;同時,如果整個機架的網路出現異常,也能保證在其它機架的節點上找到資料。為了降低整體的頻寬消耗和讀取延時,HDFS會盡量讓讀取程式讀取離它最近的副本。如果在讀取程式的同一個機架上有一個副本,那麼就讀取該副本。如果一個HDFS叢集跨越多個資料中心,那麼客戶端也將首先讀本地資料中心的副本。那麼Hadoop是如何確定任意兩個節點是位於同一機架,還是跨機架的呢?答案就是機架感知。
預設情況下,hadoop的機架感知是沒有被啟用的。所以,在通常情況下,hadoop叢集的HDFS在選機器的時候,是隨機選擇的,也就是說,很有可能在寫資料時,hadoop將第一塊資料block1寫到了rack1上,然後隨機的選擇下將block2寫入到了rack2下,此時兩個rack之間產生了資料傳輸的流量,再接下來,在隨機的情況下,又將block3重新又寫回了rack1,此時,兩個rack之間又產生了一次資料流量。在job處理的資料量非常的大,或者往hadoop推送的資料量非常大的時候,這種情況會造成rack之間的網路流量成倍的上升,成為效能的瓶頸,進而影響作業的效能以至於整個叢集的服務
2.配置
預設情況下,namenode啟動時候日誌是這樣的:
2013-09-22 17:27:26,423 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /default-rack/ 192.168.147.92:50010
每個IP 對應的機架ID都是 /default-rack ,說明hadoop的機架感知沒有被啟用。
要將hadoop機架感知的功能啟用,配置非常簡單,在 NameNode所在節點的/home/bigdata/apps/hadoop/etc/hadoop的core-site.xml配置檔案中配置一個選項:
<property>
<name>topology.script.file.name</name>
<value>/home/bigdata/apps/hadoop/etc/hadoop/topology.sh</value>
</property>
這個配置選項的value指定為一個可執行程式,通常為一個指令碼,該指令碼接受一個引數,輸出一個值。接受的引數通常為某臺datanode機器的ip地址,而輸出的值通常為該ip地址對應的datanode所在的rack,例如”/rack1”。Namenode啟動時,會判斷該配置選項是否為空,如果非空,則表示已經啟用機架感知的配置,此時namenode會根據配置尋找該指令碼,並在接收到每一個datanode的heartbeat時,將該datanode的ip地址作為引數傳給該指令碼執行,並將得到的輸出作為該datanode所屬的機架ID,儲存到記憶體的一個map中.
至於指令碼的編寫,就需要將真實的網路拓樸和機架資訊瞭解清楚後,透過該指令碼能夠將機器的ip地址和機器名正確的對映到相應的機架上去。一個簡單的實現如下:
#!/bin/bash
HADOOP_CONF=/home/bigdata/apps/hadoop/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,格式為:節點(ip或主機名) /交換機xx/機架xx
192.168.147.91 tbe192168147091 /dc1/rack1
192.168.147.92 tbe192168147092 /dc1/rack1
192.168.147.93 tbe192168147093 /dc1/rack2
192.168.147.94 tbe192168147094 /dc1/rack3
192.168.147.95 tbe192168147095 /dc1/rack3
192.168.147.96 tbe192168147096 /dc1/rack3
需要注意的是,在Namenode上,該檔案中的節點必須使用IP,使用主機名無效,而Jobtracker上,該檔案中的節點必須使用主機名,使用IP無效,所以,最好ip和主機名都配上。
這樣配置後,namenode啟動時候日誌是這樣的:
2013-09-23 17:16:27,272 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /dc1/rack3/ 192.168.147.94:50010
說明hadoop的機架感知已經被啟用了。
檢視HADOOP機架資訊命令:
./hadoop dfsadmin -printTopology
Rack: /dc1/rack1
192.168.147.91:50010 (tbe192168147091)
192.168.147.92:50010 (tbe192168147092)
Rack: /dc1/rack2
192.168.147.93:50010 (tbe192168147093)
Rack: /dc1/rack3
192.168.147.94:50010 (tbe192168147094)
192.168.147.95:50010 (tbe192168147095)
192.168.147.96:50010 (tbe192168147096)
3.增加資料節點,不重啟NameNode
假設Hadoop叢集在192.168.147.68上部署了NameNode和DataNode,啟用了機架感知,執行bin/hadoop dfsadmin -printTopology看到的結果:
Rack: /dc1/rack1
192.168.147.68:50010 (dbj68)
現在想增加一個物理位置在rack2的資料節點192.168.147.69到叢集中,不重啟NameNode。
首先,修改NameNode節點的topology.data的配置,加入:192.168.147.69 dbj69 /dc1/rack2,儲存。
192.168.147.68 dbj68 /dc1/rack1
192.168.147.69 dbj69 /dc1/rack2
然後,sbin/hadoop-daemons.sh start datanode啟動資料節點dbj69,任意節點執行bin/hadoop dfsadmin -printTopology 看到的結果:
Rack: /dc1/rack1
192.168.147.68:50010 (dbj68)
Rack: /dc1/rack2
192.168.147.69:50010 (dbj69)
說明hadoop已經感知到了新加入的節點dbj69。
注意:如果不將dbj69的配置加入到topology.data中,執行sbin/hadoop-daemons.sh start datanode啟動資料節點dbj69,datanode日誌中會有異常發生,導致dbj69啟動不成功。
2013-11-21 10:51:33,502 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for block pool Block pool BP-1732631201-192.168.147.68-1385000665316 (storage id DS-878525145-192.168.147.69-50010-1385002292231) service to dbj68/192.168.147.68:9000
org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.net.NetworkTopology$InvalidTopologyException): Invalid network topology. You cannot have a rack and a non-rack node at the same level of the network topology.
at org.apache.hadoop.net.NetworkTopology.add(NetworkTopology.java:382)
at org.apache.hadoop.hdfs.server.blockmanagement.DatanodeManager.registerDatanode(DatanodeManager.java:746)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.registerDatanode(FSNamesystem.java:3498)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.registerDatanode(NameNodeRpcServer.java:876)
at org.apache.hadoop.hdfs.protocolPB.DatanodeProtocolServerSideTranslatorPB.registerDatanode(DatanodeProtocolServerSideTranslatorPB.java:91)
at org.apache.hadoop.hdfs.protocol.proto.DatanodeProtocolProtos$DatanodeProtocolService$2.callBlockingMethod(DatanodeProtocolProtos.java:20018)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:453)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1002)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1701)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1697)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1408)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1695)
at org.apache.hadoop.ipc.Client.call(Client.java:1231)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:202)
at $Proxy10.registerDatanode(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:164)
at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:83)
at $Proxy10.registerDatanode(Unknown Source)
at org.apache.hadoop.hdfs.protocolPB.DatanodeProtocolClientSideTranslatorPB.registerDatanode(DatanodeProtocolClientSideTranslatorPB.java:149)
at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.register(BPServiceActor.java:619)
at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.connectToNNAndHandshake(BPServiceActor.java:221)
at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:660)
at java.lang.Thread.run(Thread.java:722)
4.節點間距離計算
有了機架感知,NameNode就可以畫出下圖所示的datanode網路拓撲圖。D1,R1都是交換機,最底層是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
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913864/viewspace-2696066/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師大資料學習路線Hadoop學習乾貨分享程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享MAPREDUCE程式設計師大資料
- 好程式設計師大資料學習路線分享SparkSQl程式設計師大資料SparkSQL
- 好程式設計師大資料培訓分享Hadoop入門學習線路圖程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享Hadoop階段的高可用配置程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享Hbase指令學習程式設計師大資料
- 好程式設計師大資料學習路線分享大資料之字串程式設計師大資料字串
- 好程式設計師大資料學習路線分享hadoop常用四大模組檔案程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享HDFS學習總結程式設計師大資料
- 好程式設計師大資料學習路線分享hdfs學習乾貨程式設計師大資料
- 好程式設計師大資料學習路線分享Actor學習筆記程式設計師大資料筆記
- 好程式設計師大資料學習路線分享Map學習筆記程式設計師大資料筆記
- 好程式設計師大資料學習路線分享HDFS讀流程程式設計師大資料
- 好程式設計師大資料學習路線分享AWK詳解程式設計師大資料
- 好程式設計師大資料學習路線分享UDF函式程式設計師大資料函式
- 好程式設計師大資料學習路線分享spark之Scala程式設計師大資料Spark
- 好程式設計師大資料學習路線分享Lambda表示式程式設計師大資料
- 好程式設計師大資料學習路線分享大資料之執行緒程式設計師大資料執行緒
- 好程式設計師大資料學習路線分享高階函式程式設計師大資料函式
- 好程式設計師大資料學習路線分享Scala系列之物件程式設計師大資料物件
- 好程式設計師大資料學習路線分享TCP和UDP學習筆記程式設計師大資料TCPUDP筆記
- 好程式設計師大資料學習路線分享大資料之基礎語法程式設計師大資料
- 好程式設計師大資料學習路線分享MapReduce全過程解析程式設計師大資料
- 好程式設計師大資料學習路線分享hive的執行方式程式設計師大資料Hive
- 好程式設計師大資料學習路線分享什麼是Hash表程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之抽象類程式設計師大資料抽象
- 好程式設計師大資料學習路線分享Scala系列之陣列程式設計師大資料陣列
- 好程式設計師大資料學習路線分享Scala分支和迴圈程式設計師大資料
- 好程式設計師大資料學習路線分享MapReduce全流程總結程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之泛型程式設計師大資料泛型
- 好程式設計師大資料學習路線之大資料自學路線二程式設計師大資料
- 好程式設計師大資料學習路線之大資料自學路線一程式設計師大資料
- 好程式設計師大資料學習路線分享執行緒學習筆記二程式設計師大資料執行緒筆記
- 好程式設計師大資料學習路線分享多執行緒學習筆記程式設計師大資料執行緒筆記
- 好程式設計師大資料學習路線Hbase總結程式設計師大資料
- 好程式設計師大資料學習路線之mapreduce概述程式設計師大資料
- 好程式設計師大資料學習路線分享彈性分散式資料集RDD程式設計師大資料分散式
- 好程式設計師大資料學習路線分享函式+map對映+元祖程式設計師大資料函式