- 產品
- 產品解決方案
- 行業解決方案
- 案例
- 數據資產入表
- 賦能中心
- 伙伴
- 關于
時間:2022-03-30來源:省略我瀏覽數:406次

分享嘉賓:祝江華 網易 資深大數據工程師
編輯整理:陳凱翔?亞廈股份
出品平臺:DataFunTalk
導讀:本文的主題是網易大數據HDFS的優化和實踐,下面會從三個方面來介紹網易在大數據存儲相關的工作和努力。
網易大數據平臺
HDFS在網易的實踐及挑戰
重點業務分享
01網易大數據平臺網易引入Hadoop十年有余。開源是大數據行業的發展趨勢,網易也是本著開源開放的心態來做好大數據。

近年來隨著業務的發展,網易實現了大數據跨云部署,跨云生產,為業務在生產效益上帶來了很多益處。上圖是網易大數據平臺的示意圖,從邏輯上分為六大部分:
大數據應用開發層:提供了一些大數據開發套件給業務生產使用,通常是可視化產品。業務可以通過一個簡單的SQL去查詢某個表里的數據和自己寫的Job任務。
應用場景層:與任務和數據相關的場景,提供了數據開發和數據管理相關的產品。業務在平臺中的數據以及日常的輔助功能都在這一層實現。比如查看之前運行的一些作業,使用的哪些表等等。
數據計算層:大數據離不開計算,網易實現了多種計算類型,例如離線使用Hive,計算使用Flink,Spark和一些交互性的查詢。上面兩層提交的任務經過這層判斷離線還是在線后進入到下一層。
數據管理層:各階段有統一的資源調度,網易選擇YARN來進行調度,并做了很多優化。
數據存儲層:HDFS分布式存儲。如果有業務需要高吞吐的性能,建議使用HBase。
數據源:大數據最開始是在傳統的技術上發展而來的,所以有很多結構化的關系型數據。隨著業務的發展,產生了很多音視頻數據和JSON數據這樣的半結構化數據,這些都是可以在大數據平臺打通的。
通常大數據平臺還包括一些輔助功能,作業調度使用Azkaban,身份認證使用Kerberos等等。另外整個平臺的元數據是統一進行管理,運維監控上也做統一規劃。

當前網易大數平臺已經實現億級存儲,擁有多個機房和多個集群保證務數據不會丟失。同時為了幫助業務以較小的資源實現較好的利益,網易實行存算分離,不再讓業務受限數據和計算綁定。存儲仍然是以HDFS為主。另外對業務比較關心的成本問題,網易大數據平臺提到的業務上云方案使業務可以更加專注的發展。

目前網易大數據擔任了集團內,如網易云音樂、網易嚴選、網易新聞,和集團ToB業務,如供應鏈、金融、電力傳媒等等。上面列舉的只是一部分,多個場景已經在使用我們的服務并且已經成功落地。
02
HDFS實踐及挑戰
接下來介紹HDFS的應用和優化。我們的HDFS幾乎是和大數據平臺同時引入,經過多年的技術發展在安全、高效、實踐上都有自己的心得。

眾所周知HDFS有幾個比較優秀的特點,這里回顧一下HDFS的基礎架構。HDFS通常有兩個主節點,active NamenNode和standby NameNode,并且還包含多個DataNode一起來對外提供服務。主節點主要是負責原數據管理和接收客戶端請求。如果NameNode發生故障,有HA機制可以保證高可用。數據流進來后會分配副本放置于不同的數據節點,這些數據節點通常會有自己的策略存儲在DataNode上,圖上省略了JournalNode節點。
正是由于這種架構,我們實現了集群動態擴展,可以對某個集群不停止服務的情況下將其輕易擴展到數百個節點,甚至數千個節點。另外HDFS是一次寫入任意讀機制。隨著大數據的發展,目前HDFS完全可以和多個組件進行融合,比如說Hive、Spark、Flink等等,很容易就能實現實時處理,批處理。此外,在部署上對硬件的要求也不是特別高。

和大多數廠家一樣,網易在實踐HDFS的過程中也經歷了多個階段。最開始時數百個節運行非常穩定,平時很少需要人工干預。后來隨著業務發展慢慢擴容到千臺規模。這個時候業務運行偶爾需要人工干預。在后來業務類型以及應用越來越廣,集群規模發展到數千臺節點。此時業務會出現在高峰時段響應較慢的情況,同時可能會出現數據節點在某個時刻壞盤的情況。隨著數據越來越多,元數據也越來越多,重啟時間也會相應變慢。網易在這個過程中踩過很多坑。目前我們的服務非常穩定,隨著服務越來越穩定的情況下網易正在搭建萬臺節點的集群。

目前網易在集群上有多個機房做保障,有多個自有集群和多個ToB集群業務,并且單個NameSpace也超過數千個節點,業務吞吐量每天達到了數十PB。在訪問上單個NameSpace和單個NameNode客戶端接受訪問已經達到了億級別,同時在冷熱技術上也有建樹。比如現在完全可以提供數百PB規模的冷備集群同時保證所有線上服務正常可用。這里還有一個挑戰是保證服務24小時可用。我們對服務通常是做全實時監控,對硬件做全實時監控,對一些重要的業務做隔離。

對于HDFS的挑戰來說,有一些廠商專注于集群,還有一些廠商專注于硬件。我們根據自己的發展規劃以及實際場景總結了網易遇到的兩大挑戰:
集群規模增長以及性能帶來的挑戰
數據不斷增長以及數據平衡管理帶來的挑戰
隨著業務的不斷拓展,每年重要的業務都會增加多個NameSpace來應對業務的拓展以及創新,并且在節點數上也會拓展,例如音樂、傳媒每年都會增加很多新數據。我們也會不定期搭建一些專有集群和公有集群。執行規模增長的同時也需要服務的穩定運行,只有服務穩定運行,業務才可以收益更大。隨著集群規模的增長,相應的數據也會有很多體現。集團內部有很多業務數據每個月都會增長數PB,甚至是10PB。在峰段時對于HDFS,管理數據也有很多挑戰,在管理數據成本上也會相應的增加,比如硬件成本,元數據管理成本等等。

這是當前網易的HDFS架構圖,主要是分為四層,自上而下分別是:
用戶層:這層主要判斷用戶訪問的合理性以及安全認證,這塊使用Kerberos進行認證。
代理層:主要借鑒RBF服務做代理,這塊會搭建多個Router應對峰值的請求以及平時業務的增量請求,整個Router自身也有自己更新的增量數據,比如定期更新,定期感應NameNode,近期的狀態數據等等。
元數據層:元數據用多個NameSpace組成,每個NameSpace通常有兩個NameNode,同一時刻兩個NameNode會設置一個主節點來接受客戶端的請求。這塊和代理層是一起的,因為客戶端在訪問時Router通常會有一個代理直接把請求下發到相應的NameNode上去。
數據層:數據層由多個DataNode組成,會定期向NameNode匯報心跳、增量數據、Block信息等等,這塊主要負責和客戶端的IO請求,當客戶端在發起請求的時候,通常會讓客戶申請一個可用的賬戶。在請求時會優先經過用戶層做安全校驗,校驗成功之后才會和相應的Router服務進行交互,由Router做代理,把客戶端請求轉發到相應的NameNode上。最后從?Router這邊拿到相應的請求地址和數據以及DataNode做IO通信,得到相應的數據。目前這個架構有很多好處,可以實現動態平移。NameNode有一個單點性能瓶頸,這一點可以對NameSpace做一個性能水平拓展。

對于集群規模增長主要有四個方向的優化。
服務快速響應:一個集群想要快速提升響應客戶端請求首先要保證服務的快速啟動,還有業務訪問時主節點和DataNode節點都需要高性能。
NameNode性能拓展問題:當NameSpace管理的數據越來越多時NameNode存在性能瓶頸,所以要從NameNode性能瓶頸出發。集群管理也非常重要,有一些重要的業務不應該和其他重要業務放在一起,因為有時兩個同等重要的業務放在一起可能會有相互干擾問題,這個時候需要做一些評估,把他們放在不同的NameSpace上,均衡提升NameSpace的性能。
集群監測能力:從集群來說,集群性能的好壞其實對他的監測能力也很重要,比如禁止異常流量可以提升集群性能。
業務評估:從業務角度進行出發的話我們需要和業務進行共建。對于任何一個業務來講,是否接納業務其實要根據當前集群運行的狀態以及重要性來決定。所以說要做接入前的評估,還有接入后的判斷等等。

在介紹NameSpace快速啟動優化前,先來回顧一下NameNode的啟動流程。當一個NameNode啟動時,先進入SafeMode階段,該namenode實際上變成了standy NameNode,緊接著當前NameNode會加載本地元數據文件,就是FSImage文件。完成之后NameNode會回滾未加載完成的日志數據,NameNode接收他管理的一些DataNode注冊,之后DataNode會進行全量上報,增量上報,當前的NameNode也會定期通知另一個active NameNode,生成Edit日志。這些Edit 日志也會并行保存在JournalNode 中,當前NameNode會定期去JournalNode上拉取EditLog,更新自己的內存數據。DataNode在這個過程中如果有一些新的數據變化也會快速向NameNode發送增量數據匯報。中途如果NameNode發現滿足了接管動作,比如默認情況下發生了100萬個事故,可能會觸發切換。當所有的DataNode塊匯報到99.999%整個啟動才算完成。NameNode啟動完之后就可以退出安全模式,這個過程是整個NameNode在啟動中的主要步驟。
在這個過程中有幾個地方比較耗時,一是在加載元數據的時候,也就是加載FSImage,二是NameNode在處理DataNode上報數據時,如果管理的數據非常多是比較慢的。

NameSpace啟動優化的主要原因就是提升集群穩定性和降低集群故障發生率,為業務訪問做性能優化,特別是數據量有一定規模時更要做優化策略。
根據線上實踐來看,一份元數據中,就是一份FSImage中,INODE和INODE_DIR,這兩個文件的總量會占到50%,其余的部分會在50%上下,并且整個加載過程都是串行處理。曾經發生過一個現象是在一個中級集群加載7億元數據可能需要20到30分鐘,這是比較慢的。經過我們的分析,可以從三個方面做性能提升:
加載元數據時,尤其是加載INODE,INODE_DIR可以并行加載
在校驗FSImage時,原來是單點串行,可以做成并行處理
在NameNode解析完元數據之后有一個更新內存的動作,原來也是串行處理,現在完全可以做成并行處理
這里補充兩點,在NameNode真正加載FSImage之前,對于一個比較大的文件,校驗是比較耗時的。同時在NameNode解析完之后對于串行處理元數據是非常低效的,我們也做了并行加載。

首先,校驗FSImage和加載FSImage改成了并行加載,在加載完之后,對加載INODE和INODE_DIR文件和目錄這兩部分數據,分別采用多線程的形式,然后解析數據也采用多線程,線程池的形式來加載到內存中。這樣會極大提升加載FSImage的性能,還有一部分是并行加載后數據會生成相應的格式,但這個格式主體不會變,這一塊會增加相應的幾部分用來做控制。
這幾個優化項的特點是:第一是兼容了舊的元數據主體風格,第二點是是否啟用并行加載這一點是可配置的,還有在切換生成新的FSImage時也可以使用加載舊版的FSImage形式去加載。經過線上驗證,加載FSImage優化極大的提升了性能,通常能提升60%到70%,這一塊已經在多個大型集群和中型集群中得到充分的驗證,尤其是在中型集群中,性能普遍會高于這個值。在FSImage中其實還包括其他的一部分數據,比如說IsTag,安全相關和Snapshot相關的元數據信息,這塊也可以參考上面做的優化進一步提升FSImage的性能。

NameNode處理DataNode上報過程中,尤其是全量上報FBR這一塊,在允許DataNode上報時需要先給DataNode發送一個Lease進行校驗,這點是通過HeartBeat上報處理的,然后NameNode把lease ID分發給DataNode之后,DataNode此時有機會把數據上報給NameNode,默認情況下這個Lease是6,當某一個DataNode獲得這個Lease后會把磁盤數據一次性分發,磁盤數據發送到NamaNode后NameNode還要對上報數據做一次校驗,判斷當前Lease是不是空閑,當前社區版是以磁盤校驗為主,也就是說,假如一個DataNode有12塊盤或24塊盤,上報之后會根據磁盤進行校驗,如果一個DataNode上報12塊盤之后會優先處理前6個盤,其他的盤就需要等前面處理完之后再進行排隊處理,這個過程中會有一些問題。第一是在整個過程中,DataNode整個磁盤數據不能被有效處理完,因為每次只能按照默認情況下處理6個,其他的全部需要等待。第二是Lease在線上會有很多失效的情況,這個是因為Lease默認只有幾分鐘的有效時間,同一時間可能會有很多等待,處于一個競爭狀態,這時Lease有可能失效,DataNode另外的部分沒有做完后面就需要重新上傳一次。這樣的話會極大的浪費RPC資源。在這種情況下我們將磁盤校驗以DataNode為單位校驗,當全量數據上報之后Lease會被標注一次,然后NameNode在處理完DataNode磁盤之后就不再做特殊處理了。這樣做有二點好處,第一是DataNode全量上報到NameNode之后在一個有效期的Lease范圍之內DataNode的絕大多數磁盤都會被處理,除非隊列不夠。第二是能有效避免DataNode重復上報的問題,這一點絕對能提升RPC性能。在實際生產當中通常還會做一些配置,把全量Lease值調大,具體上調到多大需要根據當前的集群來確定,這同樣對NameNode資源利用率有比較大的提升。

在大型集群上,通常元數據的量會比較多,比較大。NameNode的啟動時間可能會比較長。一個DataNode啟動之后,每隔一段時間重復上報一次全量數據到NameNode,曾經線上發生過少量的DataNode就觸發上報,一個周期過了以后他還會進行上報,但NameNode在這種情況下會有一些限制。NameNode在啟動周期內,尤其是在SafeMode期間,DataNode上報數據是不會被NameNode進行二次處理的,這是一個非常值得關注的問題。尤其是第一點,很浪費RPC傳輸資源,然后數據量很大的情況下代價也會非常大。第二點是發生在DataNode全量上報的時候,會跟其他未上報的DataNode做擠占,重復上報會占用其他多層資源,這時還有很多本來應該上報的DataNode得不到及時處理。在這塊的優化方法是在NameNode的啟動過程中如果DataNode全量上報被有效處理過一次,DataNode就不需要被再次處理了。這樣做有幾個好處:
有效保障絕大多數DataNode在NameNode重啟期間全量上報被有效處理一次。
有效避免DataNode重復上報。
較于優化之前極大減少了RPC資源的浪費。
這里要著重說明一點的是整個過程不需要增加任何接口,原因是DataNode在是否被允許全量上報期間NameNode有一個Lease認證,社區版也是這么做的。然后NameNode端如果發現有空閑的情況下就會向DataNode發送一個Lease,DataNode拿到這個Lease就進行一次全量上報,整個過程是通過心跳觸發的。對于在啟動優化這一塊除了上面這幾個部分之外,我們還做了其他的工作。比如NameNode端關于全量和增量隊列的優化,這一點在社區版里是沒有的。還有是對修復的有效控制,因為checkpoint原生版本會比較快,尤其是業務量比較大的情況下重啟時checkpoint會快速觸發。再就是在editLog滾動和拉取的時候,我們也做了一些有效的控制,并且對于DataNode端增量上報也需要做一些延遲處理。在整個NameNode重啟時間相較于優化能提升80%的性能。

下面介紹NameSpace的性能優化,NameSpace性能優化在整個HDFS范圍之內是非常重要的。優化的話其中有兩部分很重要。
第一是關于在客戶端讀寫請求時,業務端通常是從NameNode開始,這里有時候NameNode會出現響應變慢的情況,通常在業務量比較大的情況下,還有NS管理數據比較多的時候。優化做法是將部分流量分離出去形成一個單獨的服務,定期加載FSImage,更新EditLog。這里把一些查詢功能從原生的NameNode分解出去,這樣可以有效緩解NameNode壓力。目前已經在多個集群上得到充分的驗證。
第二點是對NameNode的RPC分級保障機制。在RPC對內控制上改良了優先級隊列,這能有效緩解RPC的阻塞。不過這里有一些值得注意的地方,就是在某些集群下需要對重點用戶的請求做足夠的保障,我們采用預留出資源的方法單獨處理。這塊的話就能很好地滿足重要用戶,也能均衡管理客戶端的請求。這是對RPC性能的情況,上面兩個都是對性能優化相關的特點。

HDFS作為一個分布式存儲產品,單NameSpace性能一直被人詬病,尤其隨著數據量越來越大NS流量過于集中出現訪問毛刺的狀態。因為NameNode的承載力總是有限的,在這個情況下遷移,隔離業務也不容易,這種情況就引入了IBF機制,也就是Server的聯邦機制。舊版本的聯邦機制主要是在客戶端掛載一個掛載表實現訪問映射。Router的機制較舊版的聯邦機制在Server端真正做到了對業務的全透明,Router的Server端也會定期感知NameNode狀態,假如說某個NameNode從active狀態變成standby狀態,整個過程Router會很快知道,因為Router服務會定期和NameNode進行通訊,感知到NameNode的狀態。這樣某一個業務想要換一個集群來進行訪問,業務端不需要做太多改變,只需要我們在服務端做一些更新或者改變,這對整個業務來說是非常透明的。更重要的是Router服務能非常有效的提升單NameSpace性能。我們也可以拓展多個NameSpace集群,通過一個Router來進行管理。再者我們可以將業務頻繁的遷移到其他的NameSpace上,整個業務也是無感知的。經過實踐,在一些重要的業務進行遷移后,對原集群RPC性能至少有20%的提升。在Router的基礎上,也做了一些改造性的優化,比如在NameSpace這一層,業務想要做一些重要的操作,也進行了一些隔離,例如delete操作,這樣是為了防止業務誤操作,也同時是對重要數據進行保護,在NameSpace層提供了一個特殊保護機制,對業務進行雙層保護,這點對社區版本來說是一個比較大的創新點。

在集群的優化方面,除了軟件性能以外監控也是非常重要的一點。我們通過Matrix指標和自研腳本對當前正在運行的服務做全方位監控,包括對各個服務,RPC的監控。一旦RPC出現異常,比如隊列延遲高,Handler延遲高,均能快速發現問題。還有就是對IO的監控,比如某一個DataNode的IO非常高,也能快速發現。另外對于一些基礎設施,例如cpu高還有內存高都可以做到秒級發現。如圖中對NameNode端的DataNode心跳處理耗時,平均是十幾毫秒。

在關注集群和系統本身的同時業務也是很重要的一部分。因為管理的業務量比較多,節點數也比較多,業務的融入本質上跟我們是相輔相成的。舉個例子,某天我們接受了一個業務需求,一開始我們對業務需求沒有充分了解,可能會將這個業務存于某一個重要的集群中,之后可能在某一時刻這個業務會產生比較大的流量影響其他業務。這種情況應該避免,所以在接納業務時需要做好的一點是及時了解業務需求以及可預見的增長,根據業務的重要性以及業務類型放入一個合適的集群中。平時在搭建集群的時候也要區分專有集群和公有集群,在接納業務之后也做好對整個業務的監控。如果發現異常行為,要及時進行反饋。在業務進來之后要關注業務動態,盡可能了解業務走向。

上面介紹我們在集群增長和集群性能的上的經驗,下面從數據方面做一些分享。在關注集群增長的同時也需要關注數據增長,集群增長意味著數據量以及訪問量會增加,相反數據增長也會引起對集群的關注。網易在數據增長以及數據管理也有很多優化心得,主要是三個方向:
分層管理:在數據建設方面,我們對數據做一個有效拆分,分層管理,分別搭建冷集群和熱集群應對冷數據和熱數據。
存算分離:在管理成本上,我們使用存算分離來降本增效。
引入高密硬件:為了進一步提升集群性能引入高性能設施,比如說一些高密的硬件。

一個集群的數據量大了之后再加上多副本機制,硬件的成本也會增加的比較快,我們會發現一些問題,比如一些數據的使用率其實并不高,有的數據可能一個月半個月也訪問不了幾次。還有情況是業務存的非重要的數據也是使用多副本保存,這樣性價比不高。為了將更加有用的數據放在合適的集群上面,我們規劃了冷熱集群分別存放性價比高的數據和并不太高的數據。熱數據通常還是以多副本的形式,冷數據使用EC來進行保存,使用RS6x3策略,就是將6個元數據塊生成3個加密塊。冷集群經過線上驗證,至少節省1.3到1.4的一個存儲空間。在將數據從熱數據導入到冷數據這個過程中我們還做了一些輔助產品支持自定義拷貝,比如可以按周,按小時,而且整個拷貝過程中都有Router機制支撐,保證整個業務的訪問是無感知的。數據流量遷移到另一個集群之后減輕原集群的訪問壓力,這部分在實踐中已經得到充分驗證。

說起計算不得不提到Hadoop的YARN。很多計算組件比如Hive,Spark,下層都要依托于YARN來調度相應的Task。在沒有進行存算分離之前其實是有一些缺點的,第一個缺點是存儲節點浪費,因為有些資源不能被完全利用。第二個缺點是計算節點不能完全利用內存和CPU資源。
存算分離技術,使用更少數據的數據節點資源用于計算節點,這樣有很多好處:第一是資源浪費比較少,對于計算節點可以更加充分利用整個單機資源。還有是存儲空間也會有相應的增加。把相同環境下原來存儲的數據移來做專門的存儲在現階段完全可行。
在數據管理上我們還引入了高密設備,一個是在數據節點DataNode對存儲做增強,在IO的角度下網絡利用率更高,還有是引入NVME這樣的設備,因為NVME較于傳統SSD盤其有性能上的優勢,比如在數據傳輸上具有低延時,還有并行性。另外在網絡性質上跟傳統SSD相比限制也小了。這個在實踐過程中相同環境下使用NVME可以有效提升20%以上的計算能力。

對于HDFS的性能來說,關注點不是從單一方面,需要從多個角度進行出發。這里列舉一些在日常使用,研發和優化過程中需要注意的點:
劃分業務:集群規劃方面建議按照大業務進行劃分,可以區分專有集群和公共集群,專有集群通常是為某些大的業務或者說重要的業務來進行服務,這樣可以避免其他業務影響。公共集群會存放一些少量的重要業務和非重要的業務。
分割業務:對一些重要業務有必要做分割,應該把一些重要業務分割到不同的NameSpace中,這樣可以避免相互干擾,同時也是對業務的隔離。
資源分配:在單點服務部署時需要做一些資源的側重和均衡利用。比如在同一個節點上同時有ZK服務,NameNode服務,可能每個服務都需要對GC做相應的設置,這個時候我們需要專注當前集群的這幾個服務狀態,合理配置當前硬件的利用。
NameSpace管理:對NameSpace管理,這一點是從元數據角度來出發,不建議過大,過大會影響響應,同時也會影響NameNode處理請求,數據量大的時候加上業務請求也比較多,可能會出現隊列阻塞和響應毛刺的情況。
RPC分級管理:原生的RPC是社區版的,他是FIFO的處理機制,在很多場景下有必要對RPC做分級管理。分級管理的方式有很多種,比如隊內分級,還有客戶端請求到NameNode的壓力動態感知等等。
均衡NameNode請求處理:NameNode在處理請求以及吞吐方面應該有一個均衡,因為在一個NameNode節點吞吐比較高的情況下,如果此時NameNode處理不及時,在高峰時段會出現反應回復慢的情況。
除了這些以外需要重點關注的DataNode和NameNode的心跳機制,因為DataNode是數據性的,他的存活度其實非常重要。
03重點業務分享對于技術來說,好的技術通常是離不開真實業務的驗證的,網易在大數據實踐應用場景也是非常豐富和復雜的,下面分享一個實際應用過程中的場景。

這是某個部門數倉的業務,其實很復雜。集群支持多種數據格式,半結構化數據和非結構化數據會陸續流入到集群中。而且有大量的離線任務和實時任務。在這個過程每天會有數十PB的數據出去,增長速率非常快,最重要的是這個過程需要保障24小時可用。其實這個挑戰相當大,經過一段時間和業務的溝通之后做了很多優化,目前運行非常良好。