大規模分布式存儲系統-分布式文件系統
分布式文件系統是分布式存儲系統(鍵值系統、表格系統、數據庫系統)的底層基礎部件,其所起的主要功能有兩個:一個是存儲文檔、圖像、視頻之類的Blob類型數據;另外一個是作為分布式表格系統的持久化層。
我們來看看業界是如何構建各家基礎的分布式文件系統。
Google文件系統(GFS)
GFS系統的節點可分為三種角色:GFS Master(主控服務器)、GFS ChunkServer(CS,數據塊服務器)以及GFS客戶端。GFS文件被劃分為固定大小的數據塊(chunk),由主服務器在創建時分配一個64位全局唯一的chunk句柄。CS以普通的Linux文件的形式將chunk存儲在磁盤中。為了保證可靠性,chunk在不同的機器中復制多份,默認為三份??蛻舳嗽L問GFS時,首先訪問主控服務器節點,獲取與之進行交互的CS信息,然后直接訪問這些CS,完成數據存取工作。需要注意的是,GFS中的客戶端不緩存文件數據,只緩存主控服務器中獲取的元數據,整體架構如圖1所示。
1、租約機制
GFS系統中通過租約( lease)機制將chunk寫操作授權給ChunkServer。擁有租約授權的ChunkServe稱為主ChunkServer,其他副本所在的ChunkServer稱為備ChunkServer。租約授權針對單個chunk,在租約有效期內,對該chunk的寫操作都由主ChunkServer負責,從而減輕Master的負載。一般來說,租約的有效期比較長,比如60秒,只要沒有出現異常,主ChunkServer可以不斷向Master請求延長租約的有效期直到整個chunk寫滿。GFS為每個chunk維護一個版本號,每次給chunk進行租約授權或者主ChunkServer重新延長租約有效期時,Master會將chunk的版本號加1。
主ChunkServer向Master重新申請租約并增加對應副本的版本號,如果有備副本下線的話,重新上線后如果版本號太低,會被Master發現,從而將其標記為可刪除的chunk,Master的垃圾回收任務會定時檢查,并通知ChunkServer將此副本回收掉,從以上機制可見,版本號在整個機制中起到了至關重要的作用。
2、一致性模型
GFS主要是為了追加(append)而不是改寫(overwrite)而設計的。一方面是因為改寫的需求比較少,或者可以通過追加(加上版本號)來實現,比如可以只使用GFS的追加功能構建分布式表格系統Bigtable;另一方面是因為追加的一致性模型相比改寫要更加簡單有效。這種模式下,可能出現記錄在某些副本中被追加了多次,即重復記錄;也可能出現一些可識別的填充記錄,應用層需要能夠處理這些問題(冪等)。GFS的這種一致性模型是追求性能導致的,這增加了應用程序開發的難度。
3、追加流程
圖2中,分離數據流與控制流主要是為了優化數據傳輸,每一臺機器都是把數據發送給網絡拓撲圖上“最近”的尚未收到數據的節點。
4、容錯機制
- Master容錯
操作日志+checkpoint+實時熱備。GFS Master的修改操作總是先記錄操作日志,然后修改內存。當Master發生故障重啟時,可以通過磁盤中的操作日志恢復內存數據結構。另外,為了減少Master宕機恢復時間,Master會定期將內存中的數據以checkpoint文件的形式轉儲到磁盤中,從而減少回放的日志量。所有的元數據修改操作都必須保證發送到實時熱備才算成功。
- ChunkServer容錯
GFS采用復制多個副本的方式實現ChunkServer的容錯,另外,ChunkServer會對存儲的數據維持校驗和。GFS以64MB為chunk大小來劃分文件,每個chunk又以Block為單位進行劃分,Block大小為64KB,每個Block對應一個32位的校驗和。當讀取一個chunk副本時,ChunkServer會將讀取的數據和校驗和進行比較,如果不匹配,就會返回錯誤,客戶端將選擇其他ChunkServer上的副本。
5、Master設計
由于GFS中的文件一般都是大文件,因此,文件命名空間占用內存不多。這也就說明了Master內存容量不會成為GFS酌系統瓶頸;另外,從負載均衡的角度考慮,可以限制每個Chunk-Server“最近”創建的數量;每個chunk復制任務都有一個優先級,按照優先級從高到低在Master排隊等待執行;Master會定期掃描當前副本的分布情況,如果發現磁盤使用量或者機器負載不均衡,將執行重新負載均衡操作;在進行副本重均衡時,要注意限制拷貝速度,否則會影響性能。
- 垃圾回收
GFS采用延遲刪除的機制,Master定時檢查,如果發現文件刪除超過一段時間(默認為3天,可配置),那么它會把文件從內存元數據中刪除,為了減輕系統的負載,垃圾回收一般在服務低峰期執行,比如每天晚上凌晨1:00開始。系統對每個chunk都維護了版本號,過期的chunk可以通過版本號檢測出來。Master仍然通過正常的垃圾回收機制來刪除過期的副本。
- 快照
快照( Snapshot)操作是對源文件/目錄進行一個“快照”操作,生成該時刻源文件/目錄的一個瞬間狀態存放于目標文件/目錄中o GFS中使用標準的寫時復制機制生成快照,也就是說,“快照”只是增加GFS中chunk的引用計數,表示這個chunk被快照文件引用了,等到客戶端修改這個chunk時,才需要在ChunkServer中拷貝chunk的數據生成新的chunk,后續的修改操作落到新生成的chunk上。(不改就不拷貝,只引用)
6、 ChunkServer設計
Linux文件系統刪除64MB大文件消耗的時間太長且沒有必要,因為ChunkServer是一個磁盤和網絡IO密集型應用,因此,刪除chunk時可以只將對應的chunk文件移動到每個磁盤的回收站,以后新建chunk的時候可以重用。
自動化對系統的容錯能力提出了很高的要求,Google在軟件層面的努力獲得了巨大的回報,由于軟件層面能夠做到自動化容錯,底層的硬件可以采用廉價的錯誤率較高的硬件,比如廉價的SATA盤,這大大降低了云服務的人力及硬件成本。
Google的成功經驗也表明了一點:單Master的設計是可行的。單Master的設計不僅簡化了系統,而且還能夠較好的實現一致性。另外,Master維護的元數據很多,需要設計高效的數據結構,占用內存小,并且能夠支持快照操作。支持寫時復制的B樹能夠滿足Master的元數據管理需求,然而,它的實現是相當復雜的。
Taobao File System
TFS設計時采用的思路是:多個邏輯圖片文件共享一個物理文件。通過<塊ID,文件編號>來唯一確定一個文件。
1、系統架構
- TFS整體架構
NameServer通過心跳對DataServer的狀態進行監測;每個DataServer上會運行多個dsp進程,一個dsp對應一個掛載點,這個掛載點一般對應一個獨立磁盤,從而管理多塊磁盤,TFS中Block的實際數據都存儲在DataServer中,大小一般為64MB,默認存儲三份。
TFS是寫少讀多的應用,即使每次寫操作都需要經過NameNode也不會出現問題,這大大簡化了系統的設計,同一時刻每個Block只能有一個寫操作,多個客戶端的寫操作會被串行化。客戶端首先向NameServer發起寫請求,NameServer需要根據DataServer上的可寫塊、容量和負載加權平均來選擇一個可寫的Block,并且在該Block所在的多個DataServer中選擇一個作為寫入的主副本(Primary),如果所有的副本都修改成功,主副本會首先通知NameServer更新Block的版本號,成功以后才會返回客戶端操作結果,整個流程如圖3所示。
2、討論
相比GFS,TFS的寫流程不夠優化,***,每個寫請求都需要多次訪問NameServer;第二,數據推送也沒有采用流水線方式減小延遲。這也是由特定歷史時期的特定業務需求所決定的,淘寶的系統是需求驅動,用***的成本、最簡單的方式解決用戶面臨的問題,TFS NameServer不需要保存文件目錄樹信息,也不需要維護文件與Block之間的映射關系。
由于用戶可能上傳大量相同的圖片,因此,圖片上傳到TFS前,需要去重。一般在外部維護一套文件級別的去重系統( Dedup),采用MD5或者SHA1等Hash算法為圖片文件計算指紋( FingerPrint)。圖片寫入TFS之前首先到去重系統中查找是否存在指紋,如果已經存在,基本可以認為是重復圖片;圖片寫入TFS以后也需要將圖片的指紋以及在TFS中的位置信息保存到去重系統中。去重是一個鍵值存儲系統,淘寶內部使用Tair來進行圖片去重。圖片的更新操作是在TFS中寫入新圖片,并在應用系統的數據庫中保存新圖片的位置,圖片的刪除操作僅僅在應用系統中將圖片刪除。
隨著系統的規模越來越大,商用軟件往往很難滿足需求,通過采用開源軟件與自主開發相結合的方式,可以有更好的可控性,系統也有更高的可擴展性。互聯網技術的優勢在于規模效應,隨著規模越來越大,單位成本也會越來越低。
3、內容分發網絡
淘寶CDN采用分級存儲。由于緩存數據有較高的局部性,在Squid服務器上使用SSD+SAS+SATA混合存儲,圖片隨著熱點變化而遷移,最熱門的存儲到SSD,中等熱度的存儲到SAS,輕熱度的存儲到SATA。通過這樣的方式,能夠很好地結合SSD的性能和SAS、SATA磁盤的成本優勢。