基於Alluxio的HDFS多集群統一入口的實現
來自專欄 分散式虛擬存儲系統Alluxio
基於Alluxio的HDFS多集群統一入口的實現
1. 簡介
隨著蘇寧大數據平台的規模越來越大,HDFS集群Namenode逐漸出現性能瓶頸,特別是在凌晨任務的高並發期,Namenode的RPC響應延遲較高,單次寫RPC請求甚至超過1s,嚴重影響了集群的計算性能。因此解決HDFS的擴展性問題,勢在必行。
本文將介紹在蘇寧我們是怎麼解決這個問題的,主要從以下幾個方面來展開:
- 單一的HDFS集群存在的問題和挑戰,以及原因分析;
- 將單一的集群拆分成多集群需要考慮的問題,以及多集群的方案對比;
- 如何利用Alluxio的統一命名空間來實現HDFS多集群的統一入口;
2. 單一HDFS集群的瓶頸和挑戰
下圖為蘇寧大數據平台的軟體棧,與其他各家友商的平台大同小異。HDFS作為蘇寧大數據平台的底層存儲系統,集群達到1500+台Datanode(48TB),已使用30+PB的空間,存儲了1.8億的文件和1.8億的塊,每天運行的任務量接近40萬。在凌晨計算高峰期,對Namenode最大並發請求量為3萬+。
圖1:蘇寧大數據平台軟體棧
我們使用的Hadoop-2.4.0的版本,下圖是HDFS RPC請求及處理的流程圖。
圖2:HDFS RPC請求及處理流程
從圖中可以看到,導致NameNode RPC響應延遲高的原因主要有:
- 所有對Namenode元數據的寫請求都需要獲取FSNameSystem的寫鎖,並發高的情況下,等待鎖資源會消耗較長的時間;
- EditLog和Auditlog的同步寫;
下圖是我們HDFS集群某一天寫請求響應時間的統計圖。從圖中可以看到,在凌晨3點到5點,RPC的響應時間持續在500ms左右,對上層的任務影響較大。
圖3:HDFS Namenode 寫請求的RPC響應時間
針對高峰期Namenode RPC響應延遲高的問題,我們做了如下優化:
- 優化任務,減小對HDFS的讀寫次數,特別是使用動態分區的任務;
- 將audit log由同步改成非同步;
- 設置fsImage的合併時間為1小時;
- disable掉文件系統access time的更新功能;
通過上面的優化,性能有所提升,但是並沒有達到我們預期,高峰期RPC延遲仍然很高,我們開始考慮多集群方案。
3. 多集群方案調研
設計多集群方案時,我們主要考慮的問題有:
- 如何做到對用戶透明;
- 如何做到跨集群的數據訪問;
- 集群按照何種維度進行切分;
- 系統的穩定性;
- 運維的複雜度;
帶著以上問題,我們對社區已有方案進行了調研和對比。
3.1 Federation+Viewfs
該方案在Hadoop-2.4.0版本中已經存在,是基於客戶端的配置來實現的。
優點是:
- 可以做到對用戶無感知;
- 通過客戶端的Viewfs可以實現跨集群的數據訪問;
- 很多公司在生產環境中使用,穩定性有保證;
缺點是:
基於客戶端配置實現,集群規模越大,賬戶越多,運維的複雜度會越來越高。
3.2 HDFS Router
在Hadoop-2.9.0的版本中,發布了一個新的feature -- HDFS Router。該方案將路由表做在了服務端,所有的RPC請求都先到Router,Router根據路由表的解析結果對RPC請求進行轉發。
該方案雖然可以解決Federation + Viewfs的運維複雜度問題,但沒有經過大規模生產驗證,穩定性無法保證,不敢輕易使用。
3.3 Alluxio 統一命名空間
Alluxio的統一命名空間特性,支持對不同集群的HDFS路徑進行掛載,為用戶提供統一的訪問入口。經過調研該方案,得出如下結論:對用戶訪問透明;在服務端進行掛載,運維成本可接受;Alluxio已經被多家一線互聯網公司應用於生產環境,成熟度和穩定性有保證。因此,我們決定採用Alluxio統一命名空間來實現多HDFS集群方案。
在下面的章節中,我們會介紹在設計和實施過程中遇到過哪些問題,踩過哪些坑。
4. Alluxio多集群統一入口的設計和實現
我們首先來解決一個問題:集群如何切分?只有在確定了集群的切分維度之後,才能基於該維度去做路由的設計。我們採取的切分策略是:按照賬號進行切分,一個賬號不能跨兩個集群。
如何實現對用戶透明?採用同名掛載的方式可以實現對用戶的透明,比如集群A的/user/bi路徑掛載到Alluxio空間中也是/user/bi。
確認了切分和掛載方案後,我們對Alluxio進行了測試,發現如下問題:
- 存儲同樣體量的元數據時,Alluxio Master相較於HDFS Namenode會消耗更多的內存空間。因此,做多集群的統一入口時,Alluxio Master的內存會先達到瓶頸;
- Alluxio採用的Thrift RPC框架,Alluxio客戶端和Master採用的是長連接;在凌晨計算高峰期,Master端的服務線程會被打滿,從而導致客戶端的請求都被堵住;
- Alluxio Client是以plugin的形式進行部署的,和其他組件的jar包存在兼容性問題;
針對以上問題,我們分別給出了自己的解決方案,下面會分小節做詳細介紹。首先來看下我們的總體架構圖。
圖4:Alluxio多集群統一入口的結構圖
客戶端通過多集群統一入口訪問HDFS集群的流程如下:
1. HDFS的客戶端利用Alluxio客戶端去Alluxio Master請求路由表;
2. HDFS客戶端根據返回的路由表對訪問的路徑進行解析,獲取對應的NameService;
3.請求相應NameService的Namenode,獲取文件的元數據信息;
4. HDFS客戶端根據返回的元數據信息,和對應的Datanode進行交互;
4.1 元數據量問題
針對Alluxio Master內存瓶頸的問題,我們採取的解決方案是:Alluxio和HDFS各自管理自己的元數據;下圖為各個空間的文件和元數據的示例圖。
圖5:文件內存元數據管理示例圖
從圖中可知:
- File A:表示只存儲在Alluxio的數據,沒有寫到HDFS中,該文件的元數據信息只會保存在Alluxio Master中;
- File B:表示只存儲在HDFS的數據,沒有load到Alluxio的內存中,該文件的元數據信息只會保存在HDFS的Namenode中;
- File C:表示文件同時存儲在Alluxio和HDFS中,此時C文件的元數據信息會同時出現在Alluxio Master中和HDFS Namenode中;
元數據分開管理會存在數據一致性的問題,但在我們當前的使用場景中,並不會使用Alluxio進行實際的數據存儲,算是從應用場景上規避了這個問題。
4.2 Alluxio客戶端和Master之間的長連接問題
針對client和Master存在長連接的問題,我們的解決方案是:client主動去關閉,在需要時再重建連接。關閉重連的消耗時間如下圖所示,針對離線集群來說,1ms左右的性能損耗是可以接受的。
圖6:客戶端關閉重連的壓測結果
4.3 jar包兼容性問題
Alluxio客戶端jar包和其他組件的jar包衝突問題,我們採用了業界常用的方案:利用maven的shaded插件將Alluxio客戶端runtime相關的jar全部shaded住。
5. 性能測試
在上線之前,我們對該方案進行了壓測。模擬20個和50個賬戶,並發對單集群和多集群(2個集群)分別進行壓測,結果如下:
備註:壓測的讀寫比例請求是按照生產的實際讀寫比例的請求來進行的;1 Transaction =mkdir:create:listStatus:getfileinfo:open:rename:delete=1:4:5:71:40:3:1,因此1TPS對應底層125個RPC請求。
從壓測數據來看,在採用兩個集群的方案中,HDFS的TPS增加了40%,響應時間下降了22%。相信隨著蘇寧的業務的不斷增多,多集群的解決方案會取得更好的效果。
後續優化
在使用的Alluxio做多集群統一入口的時候,我們發現如下問題需要去優化,我們將在Q2解決:
- Client需要保存各個集群Namenode的地址信息,不利於客戶端的運維。可以將HDFS的配置信息也存儲在Alluxio的Master端;
- Alluxio Master不能感知底層HDFS Namenode的Active和Standby狀態,導致客戶端在訪問Namenode的時候,會按照配置文件的先後順序會去嘗試;
後記
在今年的3月份我們將HDFS升級到Hadoop-2.8.2的版本中,得益於新版本對HDFS寫流程的優化,升級之後,Namenode的RPC響應延遲大幅下降,寫請求的峰值時間下降到50ms以下。
但該版本中Namenode的內存使用量和FSNameSystem的writeLock問題依然沒有得到解決。隨著業務和數據量的持續增長,仍然會存在較嚴重的性能問題。因此對於可以預見的大規模使用場景,提前做多集群方案,仍然非常必要。
致謝
感謝南京大學的顧榮博士和Alluxio社區的Bin Fan博士對這個項目支持,在設計和開發的過程中,兩位專家給予了很多幫助;同時也感謝南大PASA實驗室的黃志和凱旋參與本項目的測試工作。
推薦閱讀:
※MIT 6.824學習指南(1)
※Hadoop就是「存儲」加「計算」這麼簡單
※Hadoop機架感知
※Hadoop完全分散式集群在Vmware上的部署