如何實現支持百億級文件的分佈式文件存儲

前言

文件系統是最常用的數據存儲形式,所以,常用Linux操作系統的用戶必然知道ext4、xfs等單機文件系統,用Windows操作系統的用戶也都知道NTFS單機文件系統。各種業務場景下,不同的數據都存儲於文件系統之上,大量業務邏輯就是基於文件系統而設計和開發的。提供最常用的存儲訪問方式,這是我們做文件系統的出發點之一。

另一方面,單機文件系統有其明顯限制,主要是容量、文件數量限制,以及可靠、可用性限制。單機文件系統畢竟存儲空間有限,且掉電或壞盤等故障會帶來數據不可達或丟失。通過分佈式文件系統解決這些問題,這是我們的出發點之二。

但做分佈式文件系統會面臨很多挑戰,也會面臨非常多的選擇。

Google GFS論文面世之後,Hadoop HDFS隨之誕生,HDFS的選擇是處理大文件,面向MapReduce這種非在線數據分析業務,重吞吐而非延時,對HDFS內部存儲的數據進行訪問,需要藉助其提供的專有命令行和SDK,意味着它並不是一個通用型的文件系統。它的主要架構是元數據服務(本文統一用MetaData Service的縮寫MDS來指代元數據服務)和數據服務(本文統一用Data Storage Service的縮寫DSS來指代數據服務),其中MDS是單點的,單點的MDS能做出一致的決策,爲了保證MDS可靠性,一般會選擇再做一個備份。HDFS的DSS則可以是很多個。因爲文件大小和形式固定,元數據量不會太大,因而理論上單點MDS就可以支撐,不過單MDS仍限制了集羣的規模。

 

HDFS之後,出現了一些其他的開源分佈式文件系統,比如MooseFS。它也是類似的MDS+OSS架構,區別於HDFS的是,MooseFS沒有對運行其上的業務做假設,它沒有假設業務是大文件或海量小文件,也就是說,MooseFS的定位是像ext4、xfs、NTFS等單機文件系統一樣的通用型文件存儲。其實MooseFS底下用的就是單機文件系統,可以認爲它只是將多臺機器上的多個單機文件系統做了一個“邏輯上”的聚合,之所以這麼說,是因爲從數據角度,它主要是實現了一個多副本功能,而副本間的數據一致性並沒有去嚴肅地保障。從元數據角度,MooseFS提供了一個本質上就是單機的MDS,但爲了保證元數據的可靠性,MooseFS通過某些機制,接近實時地備份了元數據。

另外一個更爲知名的開源分佈式文件系統就是GlusterFS了,相比MooseFS等文件系統,GlusterFS的明顯特點是它的“無元”架構,即它沒有獨立的MDS,GlusterFS使用一致性哈希算法去定位元數據和數據。我們在設計和開發自己的文件系統時,並沒有選擇這樣的架構,因爲它的缺點非常明顯,例如元數據操作性能很差,而文件系統日常使用中,對元數據的操作佔日常操作的比例比極高(50%以上);此外,這種“無元”的文件系統架構對故障的應對不夠靈活,服務器進入集羣或退出集羣都會引起一致性哈希算法的重新計算,從而帶來部分數據的遷移,進而影響業務IO。

近兩年來,CephFS成爲開源分佈式文件系統的一顆璀璨新星。Ceph的RADOS對象存儲層是一個理論完備且實現優秀的系統。CephFS基於RADOS,它的元數據和數據都是存儲到Ceph RADOS之中。Ceph的哲學是首要確保數據穩定性而輕性能,但現實應用中性能往往也是強需求之一,某些場景甚至要求更看重性能。CephFS架構上利用了RADOS,它的MDS數據也存儲到RADOS上,而不是存儲到本地硬盤,理論和實現角度上看,這種做法可以複用RADOS,但也帶來了較大的性能衰減。

CephFS MDS是支持Active-Active模式的,MDS不再是單點,多個MDS共同維護一個統一的命名空間。CephFS實現了它自己提出的動態子樹劃分算法,其目標是根據文件系統熱點情況對MDS做動態的壓力均衡。不過在大規模生產環境中,這個功能會帶來運維的複雜度,因而實際被開啓的不多。

人工智能、移動互聯時代的一大數據特徵,就是海量文件,爲了做一個支持百億級文件的分佈式文件系統,我們該如何思考和設計呢?

方法論

在確定“方法論”之前,我們要先建立一些原則性認識。

其一是不會有one size fits all,我們不可能兼顧所有,必須有側重點,有側重就會有捨棄。“取捨”,相信是大多分佈式開發者的心得。比如分佈式系統,我們不可能突破CAP理論限制。面對各種各樣的業務需求,如果我們只滿足CP,有的業務對A有強需求怎麼辦?如果我們只滿足AP,那相信我們強調數據一致性的存儲工程師就不願意動手,因爲我們深知數據穩定是要堅守的底線。因此我們會細化,會支持針對業務的CA可以進行一定程度上的配置。

其二是要圍繞“主線”去做設計,否則上層的實現會積重難返。我們的核心主線之一就是支持百億千億級別文件海量文件。從這個主線出發,我們會去針對性地思考關鍵問題,去做要點設計。我們都知道,核心設計決定未來。前面討論到的MooseFS和GlusterFS等,爲我們衆多分佈式系統研發者提供了學習案例,在它們基礎上實現不了百億級文件,因爲已經積重難返。

下面從這兩個原則出發,來討論一下我們設計自己的分佈式文件系統時考慮的要點。

要點設計

要支持百億級文件,從前面“方法論”提出的大思路出發,我們認爲要實現的關鍵點有以下幾點。

採用中心元數據服務器(即MDS)

這幾乎是必然選擇,只有使用了MDS,CAP中的A才更爲可控,系統的整體架構也更加清晰,故障處理更加自如,數據放置策略、故障恢復策略也將更加方便和可控,因爲這些行爲都在MDS控制之下。

我們使用多MDS共同組成一個統一的命名空間,爲了支持百億級,對目錄樹必須做切分。圍繞“切分”思路,我們可以做多種切分策略,不同策略有不同的效果。如何做策略就是工程實踐問題了,從項目管控以及工程實現的複雜度角度考慮,我們目前實現的策略是按目錄哈希切分策略,這已經能滿足大多數場景的需求。在未來,我們會再實現其他策略。

MDS的另一設計要點是,是否使用本地硬盤。產生這點考慮,是借鑑到了CephFS的經驗,CephFS複用RADOS,有好處也有壞處,壞處是性能受到較大影響,好處是工程實踐角度更爲清晰。我們認爲,對元數據的操作要更重視性能,因此我們堅定地選擇了MDS直接對接本地硬盤。

選擇MDS使用本地硬盤後,下一個要考慮的要點是,是否直接使用本地MDS節點的文件系統,如ext4或xfs。使用本地文件系統,開發和實現會更加高效,,目前我們的選擇是直接使用MDS的本地文件系統,將來,爲了進一步提升MDS的操作性能,我們會直接操作裸盤的KV系統。

數據存儲(即DSS)要點

DSS主要思路是bypass文件系統,跟MDS bypass文件系統類似,這裏有兩個階段的考量,第一階段利用本地文件系統,能快速實現功能。第二階段是bypass文件系統,DSS直接操作裸盤,即做出一個獨立的單機存儲引擎,我們的主要考慮點是單機文件系統不利於海量小文件的存儲和管理;其次,單機裸盤存儲引擎,有助於我們追求更極致的性能,裸盤引擎更利於將來我們對NVMe等新型硬件和SPDK等新型技術棧做深入整合。目前,我們已經推出了基於裸盤的DSS存儲引擎。

集羣管理要點

分佈式集羣中,如何對節點是否離線、是否加入等關鍵事件進行判定,也是要考慮的核心問題之一。我們將這些任務交給集羣管理節點,或稱爲monitor來處理。如何實現monitor集羣,不需要多多考慮,基本上是實現一個paxos集羣,近幾年來用raft是一個“流行”趨勢。

副本機制和CAP開關

副本機制是分佈式系統實現數據可靠性的關鍵思路,它帶來的CA問題將是面對不同業務時需要考慮的均衡點。如“方法論”所述,我們將CA的權衡做成選項,在不同應用場景中可以有不同的側重。在這個簡單思路之上,魔鬼就在複雜的細節裏,難點主要在工程實踐之中,充足的測試是驗證這一機制的方法。

“瑞士軍刀”式功能開關

要實現百億級分佈式文件存儲,以上討論了我們的出發點和“方法論”的關鍵要點。基於這些點做出來的系統是“骨架”完整的。

但仍如“方法論”所說,沒有one size fits all的系統,我們接觸的客戶需求都是各種各樣的,不會一個系統能滿足所有業務場景和需求。因而我們的思路是在上面的核心之上,去做豐富的功能,並將主要功能做成開關式控制,某些甚至支持運行時調整。

下面討論一些主要的功能

分池存儲

一個較大規模的分佈式集羣中,往往會引入不同類型的存儲設備。另一方面,用戶的多種業務中,往往有關鍵業務和非關鍵業務之分。這兩個角度,不管從哪個角度來考慮,我們都發現,有將物理資源分池管理的必要性。因此我們實現了對物理資源分池管理的功能,也可稱之爲分組、分zone,叫法無所謂,其核心要義是提供物理資源劃分的能力。

我們實現了這個機制,目前基於這個機制,我們實現了故障域劃分的效果,將資源分配到不同池,實現物理上的故障域劃分,減小故障時的影響。

分層存儲

有不少業務會存儲大量冷數據,對冷數據,往往追求存儲成本的節約。如果用戶提供了SSD和HDD,並計劃將海量的HDD空間用作冷存儲,用少量的SSD空間用作熱存儲。我們可以將HDD空間分成一個池,將SSD空間分成一個池,邏輯上將SSD池架設到HDD池之上,實現一個分層存儲的功能,將SSD池的冷數據轉移到HDD池中去。

數據壓縮

這個功能需求往往伴隨分層存儲存在,針對冷數據存儲,用戶業務往往會再使用我們的數據壓縮功能先做數據壓縮。

後記

本文“囫圇吞棗”般介紹了我們是如何去思考和設計百億級分佈式文件系統的。當前網絡資源豐富,開源發達,通過借鑑其他系統的經驗,再加上以前的積累,我們對做一個百億級分佈式文件系統形成了自己的理解。簡單來說做百億級分佈式文件系統,首先是一個思路問題,其次是也很有挑戰的工程實踐。本文主要簡單地討論了整體“思路問題”部分,以後有機會我們再一起來討論小模塊的設計細節和實現問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章