本文為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), 顯著改善整體的可伸縮性。
圖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表的情況。
圖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算法進行數據映射
圖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内部有更好的網絡資源。在這個設計裡幹預式的錯誤被忽略, 任何随後的恢複都可可靠的保持副本一緻性。
圖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的表現不會變差。
圖5 OSD寫性能,橫線表示物理磁盤的寫上限,副本數對osd吞吐的性能影響很小, 當OSD數目固定,
圖6 EBOFS與通用文件系統的使用對比,盡管小塊文件的寫會存在文件鎖的問題, 當塊大小大于32KB
6.1.2 寫延遲
圖7 不同寫大小和副本數情況下的同步寫延遲,對于小的寫,兩個以上的副本數會産生很小的額外消耗,因為副
圖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)
圖9: 使用本地磁盤,通過減少初始的網絡來回減低了寫延遲;讀受益于緩存,當readdirplus或者
圖10:Per-MDS吞吐在不同的工作負載和集群大小下, 當集群大小增長到128的節點時,效率與最好
MDS緩存減少了readdir時間,之後的stats并不受影響,因為索引節點内容嵌入到目錄中,一個OSD訪問可以使得目錄内容能夠被放入MDS緩存中。通常,累加的stat時間主要由大目錄操作占據,後來的MDS交互會被readdirplus消除,它能夠把stat和readdir操作封裝為一個操作,或者通過放松POSIX, 允許stats跟在readdir之後時,從客戶端的緩存中提供外界服務,這是ceph默認設置。
6.2.3 元數據擴展
圖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的動态子樹分區是一個獨特的可伸縮的,高效的方法, 可在不同工作負載中有保持良好的适應性。
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!