Ceph:一個可擴展,高性能分佈式文件系統

本文為Sage A. Weil論文《Ceph: A Scalable, High-Performance Distributed File System》的譯文。

摘要

我們開發Ceph,一個分佈式文件系統,它提供了優秀的性能、可靠性和可伸縮性。Ceph通過用一個偽隨機數據分佈函數(CRUSH)替代分佈表來最大化的分離數據與元數據管理,這個算法用於異構和動態不可靠的對象存儲設備(OSD)集群。我們利用設備上半自治的OSD智能分佈數據副本,故障檢測和恢復,這些OSD運行專門的本地對象文件系統。動態分佈元數據集群提供了非常有效的元數據管理並無縫地適應各類文件系統的工作負載。多種工作負載下測試顯示, Ceph具有良好的I / O性能和可擴展的元數據管理,支持超過每秒250000次元數據操作。

1. 概述

系統設計者一直試圖提高文件系統的性能,文件系統的性能直接影響應用的整體性能。科學和高性能計算社區是推動分佈式存儲系統的性能和可伸縮性的主要力量, 他們會幾年預測一下通用需求。傳統的解決方案(比如NFS),以提供一個簡單的模型,其中服務器端export文件系統,客戶可把它映射到本地user-space。雖然被廣泛使用,但集中式的客戶機/服務器模型已被證明是可擴展性的一個重要障礙。

最近越來越多的分佈式文件系統採用了基於對象的存儲架構,智能對象存儲設備(OSD)取代傳統硬盤, OSD可將CPU、網絡、本地緩存與底層磁盤或RAID這些資源整合。OSD用大得多的讀寫字節大小範圍(往往大小不等)的對象取代傳統的塊接口,利用設備本身負責底層塊分佈。客戶通常與元數據服務器交互(MDS)執行元數據操作(open、rename),而直接與OSD交互負責執行文件I / O(read,write), 顯著改善整體的可伸縮性。

由於很少或根本沒有分佈元數據工作負載,系統採用這種模式仍然有可擴展性限制。繼續依賴傳統文件系統的分佈列表和inode表或不把智能利用到OSD上會進一步限制系統可擴展性、性能、可靠性和成本。

我們提出Ceph,這個分佈式文件系統提供優秀的性能和可靠性,同時承諾優秀的可擴展性。我們的架構是基於PB級別以及本質上動態的假設,動態的定義:大系統不可避免地逐步建立,節點失敗是常態,而非例外, 工作負載隨時間不斷變化。

Ceph分離數據和元數據操作,通過CRUSH生成代替傳統文件系統的文件分佈表。這使得Ceph在OSD中利用智能解決數據訪問的複雜性,更新序列化,複製和可靠性、故障檢測和恢復。Ceph利用高度自適應分佈式元數據集群,顯著提高元數據訪問的可擴展性,通過它也提高整個系統的可擴展性。通過討論目標和一些工作負載的假設促使我們選擇合適的架構設計,分析這些設計對系統的可擴展性和性能的影響,並用我們的經歷來實現一個系統原型。

2系統概述


Ceph:一個可擴展,高性能分佈式文件系統

圖1 基本架構


Ceph文件系統有三個主要組件: 客戶端:暴露near-POSIX的文件系統接口給主機或進程; OSD集群:存儲所有數據和元數據; 元數據服務器集群:管理名空間(文件名和目錄),協調安全與一致性(見圖1),說Ceph接口為near-POSIX在於,它為了更好地結合應用的需要和提高系統的性能,它擴展了POSIX接口,並可有選擇地放鬆一致性語義。

此架構目標是可擴展性(數百PB甚至更多),性能和可靠性。可擴展性包括整個系統的存儲容量和吞吐量以及每個客戶端,目錄或文件的性能。我們的目標工作負載可能包括數萬或數十萬host併發讀取或寫入同一個文件或在同一目錄中創建文件。這樣的場景常見於超級計算集群上運行的科學計算應用程序,今天的超級計算也就是明天的通用工作負載。更重要的是,我們設定的情景是:分佈式文件系統工作負載本質上是動態的,會有大的數據變化和動態的元數據訪問,和隨時間變化的數據。Ceph直接解決擴展問題, 同時實現高性能、可靠性和可用性,是通過三個基本設計實現的:分離數據和元數據,動態分佈式元數據管理和可靠的自動分佈的對象存儲。

分離數據和元數據

Ceph最大化的分離文件元數據管理和文件數據存儲。元數據操作(open、rename等)由元數據服務器集群管理,而客戶可直接通過OSD執行文件I / O(讀和寫)。基於對象存儲可很好的改善文件系統的可擴展性,可小塊分配數據到存儲設備。相比現有基於對象的文件系統取代長的文件塊列表為對象列表, Ceph中完全消除分配列表的設計。相反,文件數據條帶化到可計算到的命名對象, 是通過CRUSH算法分配對象存儲設備。這樣可通過一個文件計算(而不是查找)得到對象的名稱和位置, 可避免維護和分發對象列表, 簡化系統的設計, 並減少了元數據集群工作負載。

動態分佈式元數據管理

因為文件系統元數據的操作佔據典型文件系統一半的工作負載,所以有效率的元數據管理肯定能提高系統整體性能,Ceph利用了一個新的元數據集群架構,基於動態子樹劃分,它適應性的智能的分配職責,可在十個甚至上百個MDS上管理文件系統目錄結構,一個動態的層次分明的分區在每MDS工作負載中被保留位置,可促進有效更新和預取,可共同提高工作負載性能,值得注意的是,元數據服務器的負載分佈是基於當前的訪問狀態,使Ceph能在任何工作負載之下有效的利用當前的MDS資源,獲得近似線性擴展性能

可靠的自動分佈的對象存儲 RADOS

由上千臺設備組成的大系統是動態的: 他們數量慢慢增加,新存儲加入,舊的存儲捨棄,設備的故障也會頻繁發生,同時大的數據塊被創建,遷移和刪除,所有這些影響因素都需要分佈式數據能夠有效的利用現有資源並維持所需水平的數據備份,Ceph承擔著對存儲數據的OSD集群進行數據遷移,備份,故障檢測,故障修復的責任。OSD可提供獨立的邏輯對象存儲給客戶端和元數據服務器,這樣使得Ceph能更加有效的利用計算資源處理能力(CPU和內存),以使每個OSD實現可靠、高可用性的線性擴展性能的對象存儲。 接下來會描述Ceph客戶端,元數據服務器和分佈式對象存儲的操作和他們怎樣被Ceph架構中優秀特性所影響,我們也會描述Ceph原型的現狀。

3.客戶端操作

通過描述客戶端操作可介紹Ceph的各個組件的操作以及這些組件與應用程序的交互。Ceph客戶端跑在每個主機上,這些主機上會跑應用,客戶端會給予應用一個文件系統接口,在Ceph原型中,客戶端的代碼運行在用戶空間,並且可以通過直接Link到它或者利用FUSE【一個用戶態的文件系統接口】把它作為一個掛載點文件,每個客戶端包含它自己的文件數據緩存,獨立於內核頁或緩衝區緩存,可被客戶端上的應用程序直接使用。

3.1 文件I/O 和性能

當一個進程打開一個文件,客戶端發送一個請求給MDS集群,MDS轉換文件名為文件inode,這個inode包含唯一的inode號、文件所有者信息,模式,大小和其他的per-file元數據,如果文件存在並且訪問被允許,MDS會返回inode號、文件大小以及文件數據到對象的條帶化映射策略的相關信息,MDS可能給客戶端一個權限(如果之前沒分配),這個權限指明何種操作被許可,現在權限包含四種:分別控制客戶端的讀,緩存讀,寫,緩存寫,將來可能包含加密鑰(讓客戶向OSD證明他們被授權去讀寫數據『現在的原型相信所有的client)。此外,MDS還會管理文件的一致性語義。

Ceph用一系列條帶化策略管理文件數據到對象序列的映射,為了避免任何文件分佈的元數據, 對象名稱簡單地由文件inode編號和條帶編號結成,然後對象副本利用CRUSH算法分佈到OSD集群,舉例來說, 當一個或多個客戶端打開一個文件以進行讀訪問, MDS負責授權客戶端讀和緩存文件內容。當擁有inode號、文件格式和文件大小, 客戶端能夠得到包含文件數據的所有對象的名稱和位置,並且是直接從OSD集群讀取的。任何對象或字節範圍如果不存在就被定義為“文件洞”, 或空。類似地, 如果一個客戶端打開一個文件進行寫操作,則被授權buffer寫,它在文件中任何字節生成的任何數據都會被寫入適當的OSD中的對象上,客戶端不再關閉文件,而是提供給MDS新的文件大小(最大的寫入字節數)。

3.2 客戶端同步

POSIX語義要求讀先於寫,寫是原子寫(如: 內容的覆蓋,併發寫會有順序問題),當一個文件被打開,被多個客戶端寫或者讀+寫,MDS將撤銷之前的問題讀緩存和寫緩衝,強制客戶端進行文件同步I/O,每個應用讀與寫操作都會阻塞直到被OSD授權,OSD存儲對象能夠有效的分擔更新序列化和同步的負載。當一個寫跨越一個對象邊界,客戶端獲得所有受影響對象的獨佔鎖(相關OSD賦予他們的), 立刻提交寫和解鎖操作去達到序列化要求,對象鎖也用於掩蓋需要鎖和大型異步寫的延遲。

毫不奇怪,同步I/O對於應用來說是一個性能的殺手,尤其進行小文件的讀寫操作時,因為存在至少一個到osd的來回的延遲消耗,儘管讀寫共享在平常操作中比較少,更多時候用於科學計算,在這些地方性能表現很好,因為這個原因,當應用對一致性要求不高時往往可放鬆一致性語義,Ceph也實現了放鬆一致性語義,可以通過全局配置項配置,其他文件系統也做了這個設計, 但這個設計確實不是一個很好的方案。

因為這個原因, POSIX上一些高性能計算的擴展被HPC社區應用(高性能計算), Ceph實現了其中一個子集。重要的是, 這些擴展包含一個O LAZY標籤, 這個標籤表示是否允許放鬆共享文件的一致性要求。追求性能的應用會管理一致性(例如,通過寫入相同文件的不同部分, 一個在HPC中的普遍模式),然後I/O同步可實現緩衝寫和緩存讀同時進行,如果需要,應用可通過以下兩個調用來做顯式同步:lazyio_propagate刷新數據到對象存儲,同時lazyio_synchronize確保之前數據刷新應用到之後的讀。Ceph同步模型因此簡易地通過在客戶端之間通過同步I/O、擴展應用接口放鬆一致性語義來提供正確的讀寫和共享寫。

3.3 名空間操作

客戶端與文件系統名空間的交互由MDS集群來管理,讀操作(如 readdir, 文件信息操作stat)和更新操作(如刪除unlink,模式修改chmod)由MDS同步應用以保證序列化,一致性,安全。為了簡單,沒有元數據鎖提供給客戶端,尤其對於HPC工作負載,回調好處很小,相反,會帶來很高的潛在複雜性。

Ceph優化了大多數通用的元數據訪問場景,一個readdir操作後緊跟著一個對每個文件的stat(例如ls -l)是一個特別普遍的訪問模式,也是一個在包含很多文件的大目錄中臭名昭著的性能殺手的操作。一個readdir操作在Ceph中僅需要一個MDS請求,它會獲取文件夾目錄,包括inode內容,默認情況下,如果一個readdir後跟著一個或多個stats操作,會提供一個暫時的緩存返回,否則緩存會被捨棄,儘管一個此時inode的修改不會被發現,一致性稍微減弱,但換來性能的提高還是值得的,這一切由文件系統擴展接口readdirplus擴展實現,它會通過目錄入口返回lstat結果(就像一些OS中getdir已經實現的)。

Ceph可以通過緩存元數據時間更久來使得一致性被進一步的消弱,有點像早期版本的NFS,它的緩存時間達到30秒,然而,這個方法破壞了一致性,有時一致性對應用很重要,比如利用stat去判斷一個文件是不是被更新,這時會發生錯誤或者等待舊的緩存數據直到timeout。

這時我們選擇再次糾正操作行為和擴展接口,下面通過一個文件上的stat操作講解,這個文件同時被多個客戶端進行寫操作,為了返回一個正確的文件大小和修改時間,MDS要立刻停止文件更新並從所有寫操作中收集最新的大小和修改時間值,通過stat返回最高值。儘管停止多個寫看起來很不可思議,但為了保證序列化也是必要的,(對於一個單一的寫,一個正確的值可通過寫客戶端得到,不用中斷別的進程),對於不要求一致性行為的應用,POSIX接口不符合他們的需求,可以使用statlite,他會利用一個bit去指出某個inode不需要保持一致性。

4 動態分佈式元數據

元數據的操作通常要佔一半的操作時間,並且位於關鍵路徑上,所以使得MDS集群對於整體性能很重要,MDS同時也面臨分佈式文件系統中擴展性的挑戰,儘管性能和I/O在存儲設備任意增加時可被度量,但元數據操作需要更大程度的相互依存關係, 使MDS擴展時的一致性和一致性管理更加困難。 文件和目錄元數據在Ceph中很小,幾乎完全由目錄入口(文件名)和inode(80字節)組成。與傳統的文件系統不同, Ceph中不需要文件分佈元數據,對象名稱使用inode號, 並通過CRUSH算法分佈到OSD。這簡化了元數據的工作負載, 並允許MDS有效管理一個非常大的文件集合(不考慮文件大小)。我們的設計通過使用一個雙向的存儲策略,和通過動態子樹分區最大化的本地化和緩存效率進一步減少元數據相關的磁盤I / O。

4.1 元數據存儲

雖然MDS集群旨在滿足大多數內存緩存的請求, 但為了安全,元數據更新必須提交到磁盤。每個MDS快速將一組大、有界、懶刷新日誌的更新元數據分佈式上傳至OSD集群。per-MDS日誌,每個幾百兆字節, 也存儲重複的元數據更新(對多數場景很常見), 這樣當舊日誌最後刷新到長期存儲,許多已經變得過時了。雖然在我們的原型中MDS恢復還沒有實現, 但是MDS失敗時的日誌設計已經實現, 另一個節點可以快速重新掃描日誌去恢復失敗節點的內存緩存的關鍵內容(為了快速啟動), 這樣得以恢復文件系統。

這些元數據管理策略提供了最好的兩個狀況:通過有效(順序的)的方式提交更新到磁盤;以及大大減少重寫工作負載, 使長期磁盤存儲佈局優化以應對未來的讀訪問。特別是, inode在目錄中被直接嵌入,允許MDS通過一個OSD請求預取整個目錄, 並利用出現在大多數工作負載中的高深度的目錄位置。每個目錄的內容作為元數據日誌和文件數據將使用相同的條帶化和分佈策略寫入OSD集群。Inode編號在元數據服務器範圍內分佈,在我們的原型中被認為是不可變的, 儘管將來他們可能會在文件刪除時回收。一個輔助錨表使極少inode有多個硬鏈接且可尋址的inode號,但這些不妨礙singly-linked文件與一個龐大而繁瑣的inode表的情況。

Ceph:一個可擴展,高性能分佈式文件系統

圖2 Ceph基於當前的工作負載來動態映射目錄層級子樹到元數據服務器,每個目錄變為熱點時會把元數據哈


4.2 動態子樹分區

對於任何給定的元數據,primary-copy緩存策略使用一個授權MDS管理緩存一致性和序列化更新。大多數現有的分佈式文件系統使用某種形式的靜態子樹分區來做這些管理(通常把數據集分成更小的靜態“卷”), 最近的一些或者實驗用的文件系統已使用散列函數分佈目錄和文件元數據, 有效地減少載荷分佈的本地性。這兩種方法主要的缺陷在於:靜態子樹分區無法應對動態工作負載和數據集,而散列函數方法會破壞元數據的本地性和元數據獲取、存儲的有效性。

Ceph的MDS集群是基於動態子樹分區策略, 自適應地分配緩存元數據,分層分佈在一組節點上, 如圖2所示。通過使用計數器統計每個MDS中元數據的訪問量。任何操作使得受影響inode及其上層節點直到根目錄的計數都增加, 從而提供每個MDS一個權值,來描述最近的載荷分佈。定期比較MDS權值, 通過遷移以保證元數據工作負載均勻分佈。共享的永久存儲和及其名空間鎖的結合保證這樣的遷移是可行的,轉移一些內存緩存的內容到新的節點, 對相干鎖或客戶端功能影響最小。新導入元數據將寫入新MDS的日誌中, 同時,還有日誌分錄新舊MDS以確保遷移是安全的 (類似於兩階段提交)。子樹分區保持以最小化前綴複製開銷同時也要保護本地性。

跨多個MDS節點複製元數據時, inode內容分為三組,每個都有不同的語義一致性:安全(owner, mode)、文件(size, mtime)、不可變性質(inode number, ctime, layout), 當不可變性質不變, 安全和文件鎖被獨立的狀態機管理,都擁有不同狀態集,並且根據不同的訪問和更新在不同狀態之間轉換。例如, onwer和mode用於路徑訪問的安全檢查,很少改變,只需要很少幾個狀態, 但是客戶端多種訪問模式的集合, 因為它反應在MDS中, 可以控制客戶端的訪問能力。

4.3 流控

分區的目錄層次結構跨多個節點,可平衡工作負載, 但不是總能應付熱點問題 (多客戶端訪問相同的目錄或文件)。只有當成為熱點時,Ceph會使用元數據分散分佈,一般情況下不引起相關開銷以及目錄本地性的損失。大量讀訪問的目錄(如,多open)就會被複制到多個節點。目錄特別大或要一個大量字節的寫(如,多文件創建)將會將其內容利用名稱散列算法分佈到集群, 均衡分配,代價是失去目錄本地性。這個自適應方法允許Ceph分區有範圍比較大的粒度, 同時可獲取粗和細粒度分區的好處, 這種策略在一些情景和文件系統非常有效。

每個MDS響應為客戶端提供涵蓋數據和任何有關inode及其祖先的副本的更新信息,允許客戶端知道與之交互的部分文件系統的元數據分區。未來的元數據操作將直接基於給定路徑前綴最後部分對主數據(更新時)或一個隨機的副本(讀取時)操作。通常客戶端知道不常訪問元數據的位置(沒有副本),並可以直接與MDS交互。當客戶端訪問訪問頻繁的元數據時, 元數據在多個MDS節點中, 客戶端可知道特定的元數據駐留在哪個的MDS,這樣熱點問題就不會存在。

5. 分佈式對象存儲

客戶端和元數據服務器視對象存儲集群(包含成千上萬的osd)為一個邏輯的對象存儲及名空間。RADOS(可靠的自動分佈式對象存儲)可管理分佈式情況下的對象複製,集群擴展,故障檢測和恢復,能夠達到線性擴展性能。

5.1 通過CRUSH算法進行數據映射


Ceph:一個可擴展,高性能分佈式文件系統

圖3 文件被條帶化為多個object,通過CRUSH算法分佈到對象存儲中

Ceph可分佈PB級數據到由上千臺設備組成的集群中,從而設備存儲和帶寬被有效的利用,為了避免負載的不均衡(例如,最新加入的設備很可能沒被使用)或負載不對稱(比如,新的訪問頻繁的數據都放到最新設備上)。Ceph採用一個策略,它隨機分配新數據到任意設備,隨機遷移一存在數據到新設備,如果設備刪除,也會重新分佈數據,這個方法是健壯的,在現有的工作負載中表現不錯。

Ceph首先通過簡單哈希算法映射對象到配置組(PGs),通過一個自適應的位掩碼控制PG數量,選擇一個值設定來平衡每個OSD的利用率(近似100PGs分佈這些OSD上), 這個值就是每個OSD上副本相關元數據的數量。放置組然後通過CRUSH算法分配到所有OSD,這個算法是一個偽隨機數據分佈算法, 能夠有效的有序映射每個PG到多個OSD, 這個OSD組會存儲對象副本, 這個方法不同於傳統方法(包括其他的對象文件系統), 數據放置組不依賴任何的塊或對象列表元數據。為了定位每個對象, CRUSH只需要放置組和OSD 的cluster map(非常簡單,負責分層描述存儲集群中設備組成)。這個方法有兩個重要的優點: 第一個, 完全分佈式, 任何部分(客戶端, OSD或者MDS)都能獨立計算object的位置。 第二點,MAP的更新會很少,幾乎能夠消除分佈式元數據的交換。因為這些, CRUSH能夠同時解決數據應該存在哪的問題和已存數據在哪的問題,通過設計,存儲集群的一些小變化對已存在的PG mapping影響很小,使的因設備故障或者集群擴展導致的數據遷移也很少。

Cluster map結構遵循集群的物理或邏輯組成並能描述可能的故障,舉個例子,一個四層架構服務器系統, 由很多OSD,機架櫃, 成排的機殼組成,每個OSD有個weight值來衡量它上面的數據量,CRUSH算法映射PG到OSD基於Placement規則, 這個規則定義了副本數和任何其他的placement限制條件, 例如,複製每個PG到三個OSD,每個都在相同的row(限制行間的副本傳輸),但是會分散到每個機架, 儘量減少接觸電源電路或邊緣開關故障。Cluster map也包含down或inactive的設備列表和時戳數量, 這個會隨著map變化會增加, 所有OSD請求通過客戶端的時戳標示,這樣會知道現在數據的分佈,遞增的map更新會被相關的OSD分享,如果客戶端的map是過期的,可利用OSD 的回覆來判斷。

5.2 備份

與像Lustre這樣的系統相比,Lustre是利用RAID和SAN設備的容錯機制來實現可靠的OSD,而Ceph中,我們假設一個PB級或EB級系統故障是正常發生的, 而不是異常發生的,並且在任何時間都有可能幾個OSD變的不可用,為了在可擴展的情況下保證系統可用和數據安全,RADOS使用多個primary-copy管理數據副本,同時用一些步驟來最小化性能影響。

數據以放置組為大小備份,map到n個OSD上(稱為n-way副本),客戶端完成所有的寫到主OSD上的對象PG中(主host),這些對象和PG被分配新的版本號,然後寫到副本OSD上,當每個複製都完成並響應給主節點,主節點完成更新,客戶端寫完成。客戶端讀就直接在主節點讀,這個方法節省了客戶端的副本之間的複雜同步和序列化,其他方式在存在其他寫或故障恢復時是非常麻煩的。Ceph的方案使得副本佔用的帶寬從客戶端轉移到OSD集群的內部網絡,OSD內部有更好的網絡資源。在這個設計裡干預式的錯誤被忽略, 任何隨後的恢復都可可靠的保持副本一致性。


Ceph:一個可擴展,高性能分佈式文件系統

圖4:RADOS會響應ack當所有的OSD複製都完成到緩存中, 當全部寫入磁盤後會給客戶端一個最後的

5.3 數據安全

在分佈式文件系統中,為什麼數據要寫入共享存儲,基本上就兩個原因,第一,客戶端想讓它們的更新對其他客戶端可見,這個應該快速,寫可見要很快, 尤其當多個寫或者混合讀寫強制客戶端去同步操作時;第二,客戶端希望知道寫數據是不是被安全的備份了,磁盤是不是正常運行或者發生故障。RADOS 把確認更新時的同步和數據安全分開,讓Ceph實現高效更新和良好的數據安全語義。圖4描述了對象寫中消息傳遞,主要是轉發更新到副本,響應一個ack在更新到所有的osd的內存緩存中,允許同步的客戶端上的POSIX 的call去返回,當數據被安全的寫入磁盤, 最後一個commit會響應給client, 也許是幾秒之後,ceph發送ack給客戶端只要在更新被完全寫入副本並能夠容忍任何OSD單點故障,儘管這樣會增加時延,默認情況下,為了避免斷電數據丟失,客戶端也會緩存寫直到他們被提交。 這種情況下要恢復的話,要在接受新更新前,回滾到前一次的確認時。

5.4 故障檢測

及時的故障檢測對保證數據安全非常重要,但是對於擴展到數千個設備的集群來說變得很困難,對於某些故障, 比如磁盤錯誤或者數據毀壞, OSD可以自己反饋自身狀態,當一個OSD網絡上不可達,這種情況則需要實時監控,在多數情況下,RADOS讓存儲相同PG的OSD互相監控,備份之間相互通路則可確認彼此是可用的, 這種方法沒有額外的通信開銷,如個一個OSD最近沒有收到一個同伴的消息,一個對這個同伴的ping操作會被髮出。

RADOS可確認兩種OSD活性,是否OSD可訪問和是否通過CRUSH算法被分配數據,一個沒有響應的OSD會被標記為down,任何作為主節點的責任(一致性更新, 副本) 會暫時交給它的放置組副本所在的下一個OSD,如果這個OSD沒有能快速修復,會被mark out, 同時其他的OSD會加入,複製out OSD上每個PG的內容。客戶端到故障OSD的操作會被轉向新的主節點。

因為大量的網絡異常會導致OSD的連接出現各種問題,一個很小的監控集群會收集故障報告, 並集中過濾瞬間錯誤或者系統自身的錯誤(比如網絡),監控器(部分被實現了)利用選舉、active夥伴監控、短期租用、兩階段提交去集中提供一致並有效的對cluster map的訪問,map更新來反映任何故障和恢復,受影響的OSD提供遞增的map更新,並利用現有的inter-OSD信息溝通在集群中擴散消息,分佈式檢測可以快速的檢測,不產生過高的開支,同時通過集中式仲裁解決矛盾發生。很重要的是,RADOS避免因系統問題導致的大範圍的數據重複制, 通過標記OSD為down而不是out(例如因電力問題導致的半數OSD故障)

5.5 恢復和集群更新

OSD的cluster map因OSD故障、修復、集群變化(比如新存儲設備的部署加入)會變化, Ceph通過相同方法捕獲所有這些變化,為了快速的修復,OSD中每個PG包含每個對象verision號和最近的變更日誌(名字+更新或刪除的對象的version號)。

當一個活的OSD收到一個更新後的cluster map,它會遍歷本地存儲的PG並利用CRUSH算法來計算自己對於這個PG是什麼角色, 是主節點還是副本節點,如果PG所在的OSD列表發生變化,或者某個OSD剛剛啟動,這個OSD則必須與PG所在的其他OSD組成夥伴關係。對於副本PG, 所在的OSD會提供當前的PG version給主OSD。如果OSD為PG的主節點,它收集現在的(和過去的)副本PG版本號,如果主節點不是最新的PG狀態, 它會從PG所在的OSD檢索最近PG變化日誌(或者一個完全的PG內容概述,如果需要), 這樣可以得到最新的的PG內容,主節點會發送給每個副本節點一個新的日誌更新(如果需要, 可以是一個完全的內容概述),這樣主節點和副本各方都能知道PG的內容。 只有當主節點決定了正確的PG內容並共享它,然後才能通過副本I/O到對象,OSD然後從它的夥伴節點檢索丟失或過期的對象, 如果一個OSD檢索到一個到一個老對象或者丟失的對象的請求, 它會先延時處理然後遷移這個對象到修復隊列的前面。

舉例來說, 假設OSD1崩潰,並標記為down, OSD2接過PG主節點的責任,如果OSD1修復好了,監控器會把它標記為up, 當OSD2收到新的cluster map更新,他會發現它現在不在是PG的主節點了, 這時會把PG的最新version發給OSD1. OSD1將會檢索最近的PG的日誌, 告訴OSD2它的內容沒問題, 然後開始處理請求, 同時所有更新的對象在後臺被恢復。 因為故障修復由獨立的OSD驅動,每個被故障OSD影響的PG將會於(非常近似)替代OSD建立時修復, 這個方法基於快速修復機制(FaRM), 減少了修復時間並提高了整體數據安全。

5.6 利用EBOFS的對象存儲

儘管大量的分佈式文件系統利用本地文件系統,比如ext3管理底層存儲,我們發現它們的接口和性能很難滿足對象存儲的工作負載,已有的kernel接口限制了我們理解什麼時候對象更新被安全提交到磁盤。同步寫或者日誌可提供安全性,但以高延時和性能下降為代價。重要的是,POSIX接口不支持數據和元數據(例如數據屬性)的自動更新事務,這個對於保持RADOS的數據一致性很重要, 作為替代方案, 每個Ceph中OSD通過EBOFS管理它的本地對象存儲,EBOFS為一個Extent和B-樹的對象文件系統,在用戶空間實現,並且直接和raw格式的塊設備打交道,並允許我們定義我們自己的底層對象存儲接口和更新語義,他把更新序列化(為了同步)從磁盤提交中(為了安全)獨立出來。 EBOFS支持自動事務(例如,在多個對象上寫和屬性更新) ,支持當內存中緩存被更新時更新返回,同時提供同步提交通知。用戶空間的方法,除了提供更好的靈活性和更簡單的實現, 同時也能避免與linux VFS和頁緩存的笨重交互, linux VFS和頁緩存是為不同的接口和工作負載設計的。當多數內核文件系統延時寫更新到磁盤,EBOFS積極安排磁盤寫,當後面的更新重寫它們時,選擇而不是取消等待的I/O操作,這會給我們的底層磁盤調度器帶來更長的I/O queue和調度效率的提高,用戶空間的調度器也能選擇最先優先級的工作負載(例如客戶端I/O恢復) 或提供qos質量保證。

EBOFS設計是一個健壯,靈活並且完全集成B-tree服務,它被用於定位磁盤上對象, 管理塊分佈和收集索引(PG放置組), 通過開始位置與長度對管理塊分配,替代了塊列表方式, 使得元數據緊湊。磁盤上的空閒塊盤區按大小存入,並按照位置排序,可以使EBOFS在寫位置或者相關磁盤數據附近快速定位空閒空間, 同時也限制長的碎片。除了對象塊分配信息,為了性能和簡單,所有的元數據都存在於內存中,即使是很大的數據元數據也是很小的。最後EBFOS採用寫時複製,除了超級大塊的更新, 數據總是寫入未分配的盤空間中。

6 性能和可擴展性

我們通過一系列工具來評估性能,可靠性和可擴展性。 測試中,客戶端, OSD和MDS都跑在雙核的linux集群上, 使用的是SCSI磁盤,通過TCP協議通信,通常情況下, 每個OSD和MDS都跑在自己單獨的host上,這樣上百個客戶端應用都可以共享這個host,這樣能更好的測試。

6.1 數據性能

EBOFS能夠提供很好的性能和安全,同時通過CRUSH算法形成平衡分佈的數據、副本,能夠使得總的I/O性能隨著OSD集群的大小變化而變化。

6.1.1 OSD的吞吐

下面計算I/O性能是通過一個14節點的OSD集群來測試的, 圖5顯示了每個OSD在不同寫入塊大小和副本數下的吞吐, 工作負載由20個節點上的400個客戶端應用組成,性能最後被磁盤讀寫帶寬限制(58MB/s)所限制, 副本數為2或3時, 磁盤I/O會增大到二到三倍,當osd數固定,副本的增加會降低客戶端的數據吞吐。圖6比較了使用EBOFS和使用其他常用文件系統(ext3,ReiserFS,XFS)的性能。客戶端同步寫入大文件,以16MB大小條帶化, 然後讀取。 儘管小的讀寫性能會有影響,EBOFS還是能最大使用現有的磁盤帶寬, 大於32KB時, 讀顯著的勝過其他文件系統,這些測試都是在一個乾淨的文件系統上測試的,早期的EBOFS設計經驗說明它會比ext3更少的存儲碎片,但是現在還是沒法評估這個, 希望將來EBOFS的表現不會變差。


Ceph:一個可擴展,高性能分佈式文件系統

圖5 OSD寫性能,橫線表示物理磁盤的寫上限,副本數對osd吞吐的性能影響很小, 當OSD數目固定,


Ceph:一個可擴展,高性能分佈式文件系統

圖6 EBOFS與通用文件系統的使用對比,儘管小塊文件的寫會存在文件鎖的問題, 當塊大小大於32KB


6.1.2 寫延遲


Ceph:一個可擴展,高性能分佈式文件系統

圖7 不同寫大小和副本數情況下的同步寫延遲,對於小的寫,兩個以上的副本數會產生很小的額外消耗,因為副



Ceph:一個可擴展,高性能分佈式文件系統

圖8 OSD寫性能保持線性,飽和在24個OSD,CRUSH和hash性能會提高,當更大PG時在OSD


圖7描述不同寫大小和副本數情況下的同步寫延遲。當主OSD同時傳輸更新到每個副本, 對於副本兩個以上時,小塊寫會有個小的延時增長,對於大塊寫,傳輸的消耗會佔主導地位,1MB大小的寫會花去13ms,當是三個副本時,會增加到2.5倍,(33ms),因為大於128KB的寫需要排他鎖和異步刷新數據客戶端部分會出現停頓。作為一種選擇,共享寫應用也可以使用O LAZY標誌位,通過放鬆一致性,客戶端可以緩存小的寫,提交大的寫,異步寫入OSD,這樣延遲就會取決於客戶端,它會寫入cache,等待數據刷新到磁盤。

6.1.3 數據分佈和可擴展性

Ceph的數據性能跟隨OSD數量幾乎線性變化,CRUSH偽隨機分佈數據,所以OSD的使用能夠通過二次或者正太分佈寫模型化,是一個完全隨機過程,利用率的方差降低,當組的數量增加:對於每個OSD100個PG,標準的偏差是10%,對於1000個是3%, 圖8描述單OSD吞吐當集群通過CRUSH分佈,一個簡單哈希算法,一個線性的條帶化策略分佈數據, 在4096或者32768個PG 在現在的OSD上,線性的條帶化策略可平衡加載最大的吞吐去提供分佈, 像一個簡單的隨機算法。他不能處理設備故障或其他OSD集群變化,因為數據位置通過CRUSH或者HASH算法都是隨機分佈的,當PG數少,吞吐會降低,原因在於OSD利用上的大方差導致請求隊列長度與客戶端負載不匹配,因為設備可能滿載,當然概率小, 性能會降低。CRUSH可以改變這種狀況,各種分佈到OSD的集群映射都可以通過cluster map標示,不像hash和線性算法,Crush最小化了數據遷移,在集群擴張的同時保持一個平衡的分佈, CRUSH算法的複雜度為o(log n),計算只需要幾十微秒, 可允許成千上萬的OSD組成的集群。

6.2 元數據性能

Ceph的MDS集群提供增強的POSIX語義, 具有很好的擴展性, 此處通過沒有任何數據I/O的工作負載來衡量它的性能,這次實驗中的OSD僅僅用於存儲元數據。

6.2.1 元數據更新延遲

首先假定延遲所關聯的元數據更新(例如,mknod,mkdir)。 一個單一的客戶端建立了一系列的文件和目錄, 為了安全,這些MDS都需要同步日誌到OSD上。假定為都沒有本地磁盤的MDS, 所有的元數據都存儲在共享的OSD集群上,同時有一個有本地磁盤有的節點作為主節點OSD來存放日誌, 圖9a 描述了在無本地磁盤的情況下,隨著副本數的增加元數據的更新延遲。0 代表沒有元數據日誌寫入,日誌會先寫入主OSD, 副本寫入其他的osd。有本地磁盤時, 初始的從MDS到OSD的寫入會花很少時間。 在無本地磁盤的情況下2x複製的更新延遲和1x差不多,由於更新同步, 這兩種情況下,2倍以上的複製會產生一些延遲。

6.2.2 元數據讀延遲

元數據讀(例如readdir, stat,open)更復雜了,圖9b描述操作累積時間(一個客戶端在10000個嵌套的目錄,在每個目錄上readdir,和在每個文件上一個stat)


Ceph:一個可擴展,高性能分佈式文件系統

圖9: 使用本地磁盤,通過減少初始的網絡來回減低了寫延遲;讀受益於緩存,當readdirplus或者


Ceph:一個可擴展,高性能分佈式文件系統

圖10:Per-MDS吞吐在不同的工作負載和集群大小下, 當集群大小增長到128的節點時,效率與最好


MDS緩存減少了readdir時間,之後的stats並不受影響,因為索引節點內容嵌入到目錄中,一個OSD訪問可以使得目錄內容能夠被放入MDS緩存中。通常,累加的stat時間主要由大目錄操作佔據,後來的MDS交互會被readdirplus消除,它能夠把stat和readdir操作封裝為一個操作,或者通過放鬆POSIX, 允許stats跟在readdir之後時,從客戶端的緩存中提供外界服務,這是ceph默認設置。

6.2.3 元數據擴展


Ceph:一個可擴展,高性能分佈式文件系統

圖11:對與Per-MDS的延遲, 分別為4 , 16, 64個節點的MDS情況下,在mkdirs操


通過在LLNL實驗室的alc Linux集群上使用430個節點分區, 圖10描述了隨著MDS集群大小變化的per-MDS吞吐,有很優秀的線性擴展性能,在mkdirs的工作負載中,每個客戶端創建一個嵌套的四級目錄,在每個目錄下帶著10個文件和子目錄,平均MDS吞吐從2000 ops/s/MDS(在一個小的集群中)到1000 ops/s/MDS,減少50%,這時集群規模為128MDS,總共有大約100000 ops/sec。當操作makefile時,每個客戶端在相同的目錄中創建上千個文件,當檢測到很多的寫時,Ceph會哈希這個共享目錄,並會放鬆這個目錄的一致性來分擔工作負載到所有的MDS節點。openshared的工作負載中每個客戶端重複的打開關閉十個共享文件。在openssh操作中,每個客戶端在一個私有目錄下重複捕獲文件系統路徑,一個例子是用一個共享的/lib 作為共享路徑,同時其他共享/usr/include, 這個目錄經常被讀,openshared and openssh+include擁有很多的讀共享, 表現出不太好的擴展性能,相信由於客戶端選擇很差的副本,openssh+lib擴展優於瑣碎的分開的makedirs, 因為它有很少的元數據變更和很少的共享, 儘管我們相信網絡上的通信內容和消息層次上的線程進一步的降低了MDS集群的性能, 我們訪問大型集群的時間有限,使得沒法有更徹底的調研。

儘管有不太完美的線性擴展, 128節點的MDS集群每秒可以做大於25萬的元數據操作, 元數據交互是獨立的數據I/O, 同時元數據的大小是獨立的文件大小,相當於幾百個字節的存儲甚至更多,這都取決於平均文件大小,舉例來說,特定的應用在LLNL實驗室的Bluegene/L建立檢查點,這個集群可能包含64000個node,並都有兩個處理器, 寫文件到相同目錄下的不同文件中,就像mkfiles一樣, 相同的存儲系統能達到6000 元數據操作/s,同時完成每個檢查點會要幾分鐘,128節點的Ceph MDS集群會在2s內完成, 如果每個文件只有10MB(算比較小的), osd的速度會保持50MB/s, 這樣的集群能達到1.25TB/s的寫速度,支撐至少25000個osd,50000用於副本。如果250GB一個OSD,那OSD集群就是6PB, 更重要的是,Ceph的動態元數據分佈允許一個MDS集群(任何大小)可以為現在的操作重定位資源 ,尤其在所有的客戶端訪問之前分配給MDS元數據,使其更適應任何靜態分區。

7. 經驗

通過一個分佈函數取代文件分佈元數據給我們帶來了驚喜,也是提供我們簡化設計的力量,儘管就函數本身而言需要了更多的需求,但當我們已知這些需求,CRUSH能夠實現必要的擴展性,靈活性和可靠性,它極大的簡化了我們的元數據操作,可提供客戶端和OSD以完整和獨立的數據分佈信息。後者使我們可實現數據複製,遷移和故障檢測,恢復。並有效的利用環境中的CPU和內存,RADOS也給未來的OSD模型的增強開啟了一扇門,例如位錯檢測(像google文件系統)和基於工作負載動態的數據副本,類似於AutoRAID。

儘管ceph試圖用現有的文件系統為本地的對象存儲,很多其他系統也是這樣做的。我們很早就認識到,一個文件系統可為對象的工作負載提供更好的性能。我們沒有預料到的是,現有的文件系統接口之間和我們的需求的差異, 在開發rados複製和可靠性機制時變得很明顯, ebofs對於我們user-space開發出奇的快,提供了非常令人滿意的性能, 接口也完全適合我們的要求。

在Ceph中一個最大的教訓是MDS負載均衡器的重要性, 它負責擴展性,和選擇什麼元數據遷移到哪和什麼時候遷移。儘管本質上我們的設計和目標顯得很簡單,分發一個演化的工作負載到成百的MDS。MDS有各種不同的性能限制,包括CPU,內存,(緩存效率), 網絡和I/O限制,這些都會在某個點上限制性能,在總的吞吐和失敗率下很難做出權衡,某些情況下的元數據分佈失衡會提高整體的吞吐。

實現客戶端接口遇到了比預期更大的挑戰。雖然使用FUSE大大簡化實現, 可避開內核, FUSE 有自己的優點。DIRECT_IO繞過內核頁面緩存,但沒有支持mmap, 迫使我們修改FUSE使得乾淨頁面失效來作為一個解決方案。FUSE執行自己的安全檢查會產生很多getattrs(統計), 甚至實現簡單的應用程序調用。最後,頁面內核和用戶空間之間的I / O限制了總體I / O。雖然直接鏈接到客戶端可避免FUSE的一些缺陷, 在用戶空間中的系統調用會引入了一組新的問題(其中大部分我們還沒有完全檢查過), 但內核中客戶端模塊不可避免。

8. 相關工作

高性能可擴展的文件系統一直是HPC社區的目標, 提供一個可承擔高負載的文件系統。儘管許多文件系統為了滿足這種需求,他們不提供相同級別的如Ceph提供的可伸縮性。大規模的系統, 如OceanStore和Farsite是為了提供高度可靠的PB存儲, 並能提供成千上萬的客戶端到成千上萬的單獨文件的同時訪問, 但不能在成千上萬的合作客戶端對一組文件訪問時提供高性能訪問,是由於如子系統的名稱查找這樣的瓶頸。相反,文件存儲系統,如Vesta,Galley,PVFS, SWIFT[5]支持跨多個磁盤條帶化數據,實現很高概率的數據轉移分佈,但缺乏可擴展的元數據訪問或健壯的數據分佈的強力支持。例如,Vesta允許應用程序允許沒有共享的元數據情形下獨立訪問每個磁盤文件數據。然而, 像許多其他並行文件系統, Vesta不提供可伸縮的元數據查找支持。因此,這些文件系統通常工作負載表現不佳, 訪問許多小文件也需要許多元數據操作。他們通常還受到塊分配問題:塊分配通過集中式或基於鎖機制, 阻礙從成千上萬的客戶對成千上萬的磁盤的寫請求的可擴展性。GPFS和StorageTank部分解耦元數據和數據管理,但受限於基於塊的磁盤和元數據分佈體系結構的使用。

網格文件系統,如LegionFS,旨在協調廣域訪問,並不是為本地文件系統提供高性能。同樣, Google文件系統是為大的文件訪問和包含大量讀和文件寫附加提供優化。像Sorrento,它是為了非posix語義的很小部分的應用程序使用。

最近,許多文件系統和平臺,包括FAB和pNFS,一直圍繞網絡附加存儲來設計。Lustre, Panasas文件系統, zFS,Sorrento,Kybos是基於對象的存儲模式,和Ceph最相似。然而,這些系統都沒有結合可擴展自適應的元數據管理,沒有結合可靠性和容錯性。Lustre和Panasas不能將任務委託給OSD, 對分佈式元數據管理,可伸縮性和性能僅提供有限支持。此外,除了Sorrento使用一致性哈希,所有這些系統使用顯式的位置圖來指定對象存儲位置,並有限支持新存儲部署時的再平衡。這可能導致負載不對稱和可憐的資源利用率,而Sorrento的散列分佈算法缺乏CRUSH所具有的對數據遷移、設備權重計算和失敗檢測的支持。

9. 未來的工作

一些核心Ceph元素尚未實現,包括MDS故障恢復和POSIX一些調用。兩個安全體系結構和協議正在考慮中, 但也未實現。我們還計劃調查關於名空間->inode轉換元數據的客戶端回調的實用性。對文件系統的靜態區域, 可能允許不打開MDS交互。還有計劃其他幾個MDS增強特性, 包括創建快照的任意子樹的目錄層次結構。

Ceph可動態複製元數據。我們計劃讓OSD基於工作負載動態調整單個對象的複製水平和跨多個OSD放置組分發讀訪問。這將允許對少量數據的可伸縮訪問, 並可能使用類似於D-SPTF機制來促進細粒度的OSD負載均衡。

最後,我們正在開發一個服務質量體系結構允許流量優先級控制和OSD-managed基本帶寬和延遲保證,除了支持QoS要求的應用,還需要有助於均衡RADOS複製和恢復。一些EBFOS的增強也在計劃中,包括改善分佈邏輯,數據檢索與驗證和位錯檢測機制。

10. 結論

Ceph完成了三個關鍵挑戰, 性能、可擴展性和可靠性。通過剝離現有文件系統的分佈表設計, 我們最大限度地分離數據與元數據管理, 允許他們獨立使用。這種分離依賴於CRUSH, 允許客戶來計算對象的位置, 而不是在分佈表中尋找。CRUSH算法可在設備故障、擴張和集群重組為常態的大型存儲集群中跨故障域執行數據複製。

RADOS利用智能OSD管理數據複製,故障檢測和恢復,低級別磁盤分配,調度和數據遷移,而不是使用任何中央服務器節點來完成這些。儘管對象可以被認為是文件,並存儲在一個通用的文件系統中, EBOFS提供更合適的語義和高性能的滿足Ceph中特定的工作負載和接口需求。

最後,Ceph的元數據管理體系結構解決了大型存儲系統中最棘手的問題之一, 即如何實現有效提供一個統一的目錄層次結構並服從POSIX語義,隨著元數據服務器數量增加性能保持良好的機制。Ceph的動態子樹分區是一個獨特的可伸縮的,高效的方法, 可在不同工作負載中有保持良好的適應性。


分享到:


相關文章: