了解hadoop的或多或少都聽說過機架感知策略,無論是balancer還是jobtracker分配作業、資料副本放置策略都會用到機架感知。那什麼叫機架感知?
首先故名思意機架感知就是感知機架,誰感知?就是hadoop系統嘛,更確切地說是hadoop能在系統內部建立一套伺服器和機架的位置拓撲圖,並且能識別系統節點的拓撲位置,知道了這些,才能做副本放置策略、作業本地化等更高層的設計。
難道說hadoop系統能自動感應集群或者機房內部的網路拓撲結構?想想看,各個公司的機房拓撲或者網路結構都不一樣,採用的裝置型別也不相同,hadoop真的那麼吊能感受到?顯然不能!hadoop系統想獲得這個網路拓撲結構,需要系統管理員的幫助。
試想一下,hadoop能構建一幅網路拓撲圖,實際的網路拓撲圖又千變萬化,管理員該怎麼弄?所以這時候hadoop有必要設計一抽象的拓撲圖結構,管理員需要讓實際的網路拓撲結構盡量地與之適配。
namenode的大管家fsnamesystem有兩個重要的成員:
networktopology clustermap = new networktopology();
這兩個東西就負責構建了機架及機架感知。
首先說拓撲邏輯類 networktopology clustermap = new networktopology();這個networktopology建構函式就搞了一把鎖就完事了:
public networktopology()
從建構函式裡似乎看不出來啥東西。我看檢視這個clustermap物件,會發現很多地方呼叫它的add、remove等操作,也許從這裡可以看清楚這個網路拓撲類的面貌:
public void add(node node)
netlock.writelock().lock();
try
if (clustermap.add(node))
}log.debug("networktopology became:\n" + this.tostring());
} finally
}
首先傳遞進來的必須是個實現了node物件,而node實際上是乙個介面類,通過ctrl+t可以看出我們熟悉的datanodeinfo也是實現了這個介面,另外還有乙個networktopology的內部類innernode也實現了這個介面,啥是innernode先不管,接著往下看。
上面的add方法先進行簡單地合法性判斷,然後拿到networktopology構建方法裡的那把鎖,add方法在註冊datanode的時候呼叫,當時傳進來的物件是datanodedescriptor,注意這一句:
node rack = getnode(node.getnetworklocation());
getworklocation,怎麼得到網路位置?讓datanode描述符獲得網路位置,datanodedescriptor繼承自datanodeinfo物件,返回的就是乙個string型別的location,初始化的時候直接寫死賦值/default-rack,如果中間沒有重新set,那麼返回的應該是/default-rack,但是datanodeinfo有個set方法,這是註冊的時候,想辦法給它確定的,這裡留下問題1,繼續往下:
上面得到乙個rack的node物件,下面又開始呼叫clustermap的add方法,注意這個clustermap是這樣的:
innernode clustermap = new innernode(innernode.root);
就是說這clustermap是乙個innernode物件,似乎代表了乙個根,這時候繼續再看innernode,可以看到這個類
先把你傳進來的東西統統強保證成ip的形式,然後看看這些ip是不是被cache住了,如果cache住了,直接就能從cache裡拿到這個機器的位置。private class innernode extends nodebase else
//特別需要注意這裡,解析乙個節點屬於哪個機架,傳入的引數可以是機器的ip也可能是機器名,所以這裡要特別注意。在編寫解析指令碼的時候,必須要考慮到這兩種情況
//否則,可能有些機器解析不了。
// resolve its network location
string networklocation;
if (rname == null) else
node.setnetworklocation(networklocation);
}
public listresolve(listnames)
listuncachedhosts = this.getuncachedhosts(names);
// resolve the uncached hosts
this.cacheresolvedhosts(uncachedhosts, resolvedhosts);
return this.getcachedhosts(names);
}
public listresolve(listnames)
if (scriptname == null)
return m;
}string output = runresolvecommand(names);
if (output != null)
if (m.size() != names.size())
} else
return m;
}
這裡就比較簡單了,看起來是呼叫乙個指令碼,然後執行這個指令碼,這個指令碼具有這樣的功能,輸入ip位址給它,它給你返回位置,我擦,這不就是讓管理員手工配置乙個機器和機架的對映關係嗎!
this.scriptname = conf.get(script_filename_key);
static final string script_filename_key = "topology.script.file.name";
配置檔案中key 「topology.script.file.name」指定的指令碼的位置,這個指令碼要有可執行許可權,完成上面的功能。
if (scriptname == null)
return m;
}
如果你沒有配置這個東西,那麼所有的節點都會在同乙個機架上,即"/default-rack"。
好了,那麼我們看一下這個指令碼該怎麼配置。
Hadoop Rack Aware 機架感知
副本的存放是hdfs可靠性和效能的關鍵。優化的副本存放策略是hdfs區分於其他大部分分布式檔案系統的重要特性。這種特性需要做大量的調優,並需要經驗的積累。hdfs採用一種稱為機架感知 rack aware 的策略來改進資料的可靠性 可用性和網路頻寬的利用率。目前實現的副本存放策略只是在這個方向上的第...
hdfs 機架感知
client 向 active nn 傳送寫請求時,nn為這些資料分配dn位址,hdfs檔案塊副本的放置對於系統整體的可靠性和效能有關鍵性影響。乙個簡單但非優化的副本放置策略是,把副本分別放在不同機架,甚至不同idc,這樣可以防止整個機架 甚至整個idc崩潰帶來的錯誤,但是這樣檔案寫必須在多個機架之...
機架感知 RackAwareness
分布式的集群通常包含非常多的機器,由於受到機架槽位和交換機網口的限制,通常大型的分布式集群都會跨好幾個機架,由多個機架上的機器共同組成乙個分布式集群。機架內的機器之間的網路速度通常都會高於跨機架機器之間的網路速度,並且機架之間機器的網路通訊通常受到上層交換機間網路頻寬的限制。在這種情況下,希望不同節...