Categories
程式開發

攜程Hadoop跨機房架構實踐


本文將分享攜程Hadoop跨機房架構實踐,包含Hadoop在攜程的發展情況,整個跨機房項目的背景,我們跨機房的架構選型思路和落地實踐,相關的改造和對未來的展望,希望給大家一些啟迪。

一、Hadoop在攜程的落地及發展情況

攜程Hadoop是從2014年引進的,基本上每年較前一年以兩倍的速度在增長,我們對Hadoop集群做了大量性能方面的改造和優化。

1)目前,HDFS存儲層面擁有數百PB的數據,數千的節點,分為4個namespace做Federation,自研了namenode proxy來路由rpc到對應的namespace,2019年初上了一套基於Hadoop 3的Erasure Code集群來做對用戶透明的冷熱存儲分離,目前已遷移幾十PB數據到EC集群,節省一半的存儲資源。

2)計算層面,搭建了兩套離線和一套在線Yarn集群做Federation,總量15萬+core,每天30萬+ Hadoop作業,其中90%為spark。所有節點分佈在四個機房,其中離線集群部署在其中兩個機房,在線集群部署在三個機房。

二、跨機房項目背景

來看下整個項目的背景。之前我們的Hadoop機器部署在金和福兩個機房,95%的機器在福。去年底,攜程自建了日機房,同時福機房的機架數達到了物理上限,沒辦法繼續擴容。另外按照目前計算和存儲的增速來看,預計2024年底集群規模會達到萬台,新採購的機器只能加在日機房,我們需要多機房架構和部署的能力。

這其中的難點在於,兩個機房的帶寬僅200Gbps,正常情況下網絡延遲在1ms,當帶寬打滿情況下,延遲會達到10ms,同時會有10%的丟包率。我們需要盡可能減少跨機房的網絡使用帶寬。

攜程Hadoop跨機房架構實踐 1

2.1 原生Hadoop架構問題

看下原生Hadoop的問題。網絡IO開銷主要來自兩方面,Shuffle讀寫和HDFS讀寫。

1)先看shuffle,MR和Spark作業的前一個stage會將中間臨時文件刷到磁盤,下一個stage通過網絡來Fetch。如果分配的map task在機房1,reducetask在機房2,就會產生跨機房流量開銷。

2)其次HDFS層面,對於讀場景,三個副本存放在不同的節點,客戶端會從namenode拿到按照距離排好序的副本信息,優先從最近的副本所在的節點讀取。但是當三個副本都和客戶端不在一個機房的情況下,就會產生跨機房讀網絡IO開銷。寫場景的話,HDFS採用Pipeline寫,選擇副本時只考慮到機架層面的存放策略,會將三個副本放在兩個機架,如果選擇的兩個機架跨機房了,也會有跨機房網絡寫開銷。

攜程Hadoop跨機房架構實踐 2

2.2 可選的方案

當時我們討論下來有兩種架構解決方案,多機房多集群和多機房單集群,兩種各有利弊。

2.2.1 多機房多集群

多機房多集群方案的優勢是不需要修改源代碼,可以直接部署。缺點是:

1)對用戶不透明,用戶需要修改配置,指定提交到某個集群;

2)運維成本較高,每個機房有獨立的集群,配置管理麻煩;

3)最重要的是第三點,數據一致性難以保證。有些公共數據需要被多個事業部訪問的話,只能跨機房讀取,這個IO無法省掉,而如果用distcp,在本機房也放一些副本以省掉這部分流量開銷的話,又會由於副本是通過不同的namenode管理的,導致數據可能會有不一致的問題。

2.2.2 多機房單集群

再來看多機房單集群架構,劣勢是需要改Hadoop源代碼,因為動了BlockManager的核心代碼邏輯,會有風險,需要做好完備的測試和驗證。但是好處也很明顯。

1)對用戶透明,用戶不需要關心作業提交到了哪個機房,副本存放在哪裡,無感知;

2)運維部署簡單;

3)因為是由一個namenode來管理副本狀態,所以可以保證多機房副本的一致性。

主要由於第一和第三點優勢,我們希望保證用戶使用時的透明性和一致性,最終選擇了多機房單集群方案。

攜程Hadoop跨機房架構實踐 3

三、先期嘗試——在線離線混部跨機房

其實對於第一種多機房多集群方案,我們之前在在線離線混部項目中採用過。當時的場景是,離線集群的資源在凌晨高峰打滿,白天低峰較空。而在線k8s集群恰恰相反,我們希望利用k8s凌晨的計算資源幫我們減輕負擔。而k8s集群部署在金和歐機房,數據沒有本地性。所以我們希望將一些cpu密集,但是對IO壓力又不大的作業,能分配到在線集群。

我們在k8s上部署了一套Yarn集群,並開發了一套作業資源畫像系統,主要是採集作業的vcore/memory使用,shuffle,hdfs讀寫等metrics。由於zeus調度系統提交的作業一般不怎麼修改,每個作業的歷史執行時間和所消耗資源都有趨同性,我們按照zeus jobid聚合,根據歷史多次執行情況分析出每個作業的資源使用趨勢。下次作業啟動時zeus會將shuffle量和hdfs讀寫量較低的作業分配到在線集群跑。

另外由於在線集群也跨了兩個機房,我們在FairScheduler上開發了基於label的調度,一個label對應一個機房,會根據每個label的負載,動態分配作業到所屬的label,一個app所有的task只會固定在一個label內執行,這樣機房間不會產生shuffle流量。該方案上線後,可以緩解離線集群8%的計算壓力。

攜程Hadoop跨機房架構實踐 4

四、多機房單集群方案

我們規劃一個事業部對應的一個默認機房,數據盡可能在同機房內流動。由此對於多機房單集群架構改造主要包括四個方面:多機房單HDFS集群,多機房多Yarn集群,自動化數據和作業遷移工具,跨機房帶寬監控和限流。

攜程Hadoop跨機房架構實踐 5

4.1 多機房單HDFS架構

先來看HDFS改造,我們改造了namenode源碼,在機架感知之上,增加了機房感知,NetworkTopology形成了三元組。這樣客戶端讀block時,計算出來和副本所在節點的距離,本地機房肯定小於跨機房,會優先讀本地機房數據。

另外我們在namenode中增加了跨機房多副本管理能力,可以設置目錄的多機房副本數,比如只在機房1設置3個副本,或者機房1和機房2各設置三個副本,對於沒有設置跨機房副本的路徑,我們會在zookeeper和內存中維護一個用戶對應默認機房的mapping關係,寫文件addBlock的時候,根據ugi找到對應的機房,在該機房內選擇節點。

Decommission或者掉節點時候會有大量的副本複制操作,極易容易導致跨機房帶寬被打爆。對此,我們修改了ReplicationMonitor線程的邏輯,在副本複制的時候,會優先選擇和目標節點相同機房的源節點來進行複制,降低跨機房帶寬。

為了持久化跨機房路徑副本信息,我們增加Editlog Op來保存每一次跨機房副本設置變更記錄,fsimage中新增了跨機房副本Section,這樣namenode只會保存一份元數據,failover切換到standby的時候也能加載出來,沒有其他外部依賴。

攜程Hadoop跨機房架構實踐 6

攜程Hadoop跨機房架構實踐 7

4.2 改造Balancer&Mover&EC

HDFS層面還有其他一些改造,比如Balancer,我們支持了多實例部署,每個Balancer增加IP範圍列表,每個機房會起一個,只balance本機房IP的datanode的數據。對於Mover,我們也支持了多機房多實例部署,因為mover是在客戶端選擇目標副本節點的,所以需要改造按照目錄的跨機房副本放置策略在客戶端來選擇合適的節點。

這邊要注意一點的是,盡量保證proxy節點和target節點在同一個機房,因為真正遷移的網絡IO是在這兩個節點發生的。另外我們在新的日機房部署了一套基於Hadoop 3的Erasure Code集群,會將一部分歷史冷數據遷移過去,目前這塊沒有做跨機房的代碼改造,我們的EC遷移程序只會遷移那些已經被遷移到日機房的BU的冷數據到EC集群。

4.3 副本修正工具-Cross FSCK

由於我們有多個namespace,跨機房版本的HDFS是一個一個ns灰度上線的,灰度過程中,其他ns的副本放置還沒有考慮機房維度,所以我們開發了Cross IDC Fsck工具,可以感知跨機房配置策略,來修正不正確放置的副本。

因為需要不停的讀取副本信息,會產生大量的getBlockLocations rpc請求,我們將請求改成從standby namenode讀,一旦發現不匹配會調用reportBadBlocks rpc給active namenode,BlockManager會刪除錯誤的副本,重新選擇新的副本。由於這個操作比較重,高峰時間對HDFS會有影響,所以我們在客戶端加了rpc限流,控制調用次數。

4.4 多機房多Yarn集群

下面來看下Yarn的改造,我們在每個機房獨立部署一套Yarn集群,自研了ResourceManager Proxy,它維護了用戶和機房的mapping關係,這個信息是和namenode共用的,都是內存和zookeper各一份。

修改了Yarn Client,用戶提交的Yarn作業會首先經過rmproxy,然後再提交到對應Yarn集群。這樣一個app所有的Task只會在一個機房內調度,不會產生跨機房Shuffle。如果要切換用戶賬號對應的機房和集群也很方便,會立馬通過zookeeper通知到所有rmproxy,修改內存中的mapping關係。

rmproxy可以多實例部署,互相獨立,同時在Yarn Client做了降級策略,在本地定期緩存一份完整的mapping關係,一旦所有rmproxy都掛了,client也能在這段時間做本地路由提交到對應集群。

adhoc和分析報表大量使用了Sparkthrift service,presto,hive service來做計算。對這塊常駐服務也做了改造,每個機房各部署一套,客戶端之前都是通過jdbc直連對應的thrift service,改造後接入rmproxy,會先從rmproxy中拿到用戶對應機房的服務jdbc url,再連接,這塊同樣對用戶透明。

攜程Hadoop跨機房架構實踐 8

五、自動化遷移工具

由於日機房的節點會按採購到貨情況逐步往上加,所以需要按照計算和存儲的容量來規劃該遷移哪些賬號,這是一個漫長的過程,希望能盡量做到自動化遷移,以BU->賬號的粒度進行遷移,我們梳理了遷移流程,分為如下四步:

1)批量設置BU對應Hive賬號開始遷移(初始為3:0,即福機房3份,日機房0份)

2)按照Hive賬號下的DB和用戶Home目錄依次設置3:3,數據複製到日機房

3)賬號和隊列遷移到日機房

4)觀察跨機房流量,回收福機房的計算和存儲資源(設置0:3)

遷移時間過程中有些注意點:

1)遷移過程會耗費大量跨機房網絡帶寬,需要在集群低峰時間執行,我們是放在早上10點到晚上11點之間,其他時間會自動暫停遷移,否則會影響線上報表和ETL作業的SLA。

2)即使在白天遷移,也需要控制遷移的速率,一方面是減少namenode本身的處理壓力,另一方面也是降低帶寬,白天也會有一些ETL和adhoc查詢需要跨機房訪問數據,若打滿的話也會有性能影響。遷移中我們會實時監控namenode的UnderReplicatedBlocks和跨機房流量metrics,根據這些值動態調整遷移速率。

3)實時監控被遷移機房的hdfs可用容量,包括不同的StorageType的,防止磁盤打爆。還有有些hive DB庫目錄設置了hdfs quota,也會由於遷移設置3:3超過quota而報錯,我們會自動暫時調高quota,等遷移整體完成後再把quota調回去。

4)公共庫表由於被多個BU都有訪問依賴,需要提前設置多機房的副本,我們有個白名單功能,可以手動設置,一般設為2:2,每個機房各放兩份。

攜程Hadoop跨機房架構實踐 9

攜程Hadoop跨機房架構實踐 10

六、跨機房帶寬監控&限流

實踐中有些BU的表,會被當做公共表來使用,我們需要識別出來,設置跨機房多副本策略。目前的hdfs audit log中,沒有dfsclient訪問datanode,datanode和datanode傳輸數據的實際流量audit信息,而我們需要這部分信息來看實際的路徑和block訪問情況,做進一步數據分析,另外當流量打爆的況下,需要有一個限流服務按照作業優先級提供一定的SLA保障,優先讓高優先級作業獲取到帶寬資源。

對此我們開發了限流服務,在dfsclient和datanode代碼中埋點實時向限流服務匯報跨機房讀寫路徑,block讀寫大小,zeus作業id等信息, 限流服務一方面會記錄流量信息並吐到ES和HDFS做數據分析,另一方面會根據作業的優先級和當前容量決定是否放行,客戶端只有獲得限流服務的Permit,才能繼續執行跨機房讀寫操作,否則sleep一段時間後再次嘗試申請。

有了實際的流量信息後,通過離線數據分析,就很容易知道哪些表會被其他BU大量讀,通過自動和手動結合方式設置這部分錶的跨機房副本數2:2。設置後跨機房Block讀請求量下降到原來的20%。跨機房帶寬原來是打滿的,現在下降到原來的10%。

攜程Hadoop跨機房架構實踐 11

攜程Hadoop跨機房架構實踐 12

七、總結與未來規劃

總結一下,本文主要介紹了攜程Hadoop跨機房實踐,主要做瞭如下改造:

1)實現單hdfs集群機房感知功能,跨機房副本設置

2)實現基於rm proxy和yarn federation的計算調度

3)實時自動化存儲和計算遷移工具

4)實現跨機房流量監控和限流服務

目前整套系統已在線上穩定運行了半年,遷移了40%的計算作業和50%的存儲數據到新機房,跨機房帶寬流量也在可控範圍之內,遷移常態化,用戶完全不需要感知。

未來我們希望能智能決定該遷移哪些賬號,大多數公共路徑設置為2:2四個副本,比通常會多加一個副本的物理存儲量,現在是設置在表層面,希望能進一步細化到分區層面,因為分析出來大多數下游作業都是只依賴最近一天或者一周的分區。所以一旦過了時間,完全可以將歷史分區設置回三副本來減少存儲開銷。最後是將跨機房的改造也應用到基於Hadoop 3的EC集群,也支持跨機房的能力。

作者介紹

昱康,攜程架構師,對分佈式計算和存儲、調度、查詢引擎、在線離線混部、高並發等方面有濃厚興趣。

本文轉載自公眾號攜程技術(ID:ctriptech)。

原文鏈接

https://mp.weixin.qq.com/s/z4G0A6axVrd9dpefEh6BsQ