深度長文:深入理解Ceph存儲架構(gòu)
點(diǎn)擊上方“開源Linux”,選擇“設(shè)為星標(biāo)”
回復(fù)“學(xué)習(xí)”獲取獨(dú)家整理的學(xué)習(xí)資料!
本文是一篇Ceph存儲架構(gòu)技術(shù)文章,內(nèi)容深入到每個存儲特性,文章由Ceph中國社區(qū)穆艷學(xué)翻譯,耿航校稿,以下是具體內(nèi)容:
目錄
第1章 概覽
第2章 存儲集群架構(gòu)
2.1 存儲池
2.2 身份認(rèn)證
2.3 PG(s)
2.4 CRUSH
2.5 I/O操作
2.5.1 副本I/O
2.5.2 糾刪碼I/O
2.6 自管理的內(nèi)部操作
2.6.1 心跳
2.6.2 同步
2.6.3 數(shù)據(jù)再平衡與恢復(fù)
2.6.4 校驗(yàn)(或擦除)
2.7 高可用
2.7.1 數(shù)據(jù)副本
2.7.2 Mon集群
2.7.3 CephX
第3章 客戶端架構(gòu)
3.1 本地協(xié)議與Librados
3.2 對象的監(jiān)視與通知
3.3 獨(dú)占鎖
3.4 對象映射索引
3.5 數(shù)據(jù)條帶化
第4章 加密
第1章 概覽
Red Hat Ceph是一個分布式的數(shù)據(jù)對象存儲,系統(tǒng)設(shè)計旨在性能、可靠性和可擴(kuò)展性上能夠提供優(yōu)秀的存儲服務(wù)。分布式對象存儲是存儲的未來,因?yàn)樗鼈冞m應(yīng)非結(jié)構(gòu)化數(shù)據(jù),并且客戶端可以同時使用現(xiàn)代及傳統(tǒng)的對象接口進(jìn)行數(shù)據(jù)存取。例如:
本地語言綁定接口(C/C++、Java、Python)
RESTful 接口(S3/Swift)
塊設(shè)備接口
文件系統(tǒng)接口
Red Hat Ceph所具備的強(qiáng)大功能可以改變您公司(或組織)的IT基礎(chǔ)架構(gòu)和管理海量數(shù)據(jù)的能力,特別是對于像RHEL OSP這樣的云計算平臺。
Red Hat Ceph具有非常好的可擴(kuò)展性——數(shù)以千計的客戶端可以訪問PB級到EB級甚至更多的數(shù)據(jù)。
譯者注: 數(shù)據(jù)的規(guī)模可以用KB、MB、GB、TB、PB、EB、YB等依次表示,比如1TB = 1024GB。
每一個Ceph部署的核心就是Ceph存儲集群。集群主要是由2類后臺守護(hù)進(jìn)程組成:
Ceph OSD守護(hù)進(jìn)程:Ceph OSD為Ceph客戶端存儲數(shù)據(jù)提供支持。另外,Ceph OSD利用Ceph節(jié)點(diǎn)的CPU和內(nèi)存來執(zhí)行數(shù)據(jù)復(fù)制、數(shù)據(jù)再平衡、數(shù)據(jù)恢復(fù)、狀態(tài)監(jiān)視以及狀態(tài)上報等功能。
Ceph 監(jiān)視器:Ceph監(jiān)視器使用存儲集群的當(dāng)前狀態(tài)維護(hù)Ceph存儲集群映射關(guān)系的一份主副本。

Ceph客戶端接口與Ceph存儲集群進(jìn)行數(shù)據(jù)讀寫上的交互。客戶端要與Ceph存儲集群通信,則需要具備以下條件:
Ceph配置文件,或者集群名稱(通常名稱為ceph)與監(jiān)視器地址
存儲池名稱
用戶名及密鑰所在路徑
Ceph客戶端維護(hù)對象ID和存儲對象的存儲池名稱,但它們既不需要維護(hù)對象到OSD的索引,也不需要與一個集中的對象索引進(jìn)行通信來查找數(shù)據(jù)對象的位置。
為了能夠存儲并獲取數(shù)據(jù),Ceph客戶端首先會訪問一臺Ceph mon并得到最新的存儲集群映射關(guān)系,然后Ceph客戶端可以通過提供的對象名稱與存儲池名稱,使用集群映射關(guān)系和CRUSH算法(可控的、可擴(kuò)展的、分布式的副本數(shù)據(jù)放置算法)來計算出提供對象所在的PG和主Ceph OSD,最后,Ceph客戶端連接到可執(zhí)行讀寫操作的主OSD上進(jìn)而達(dá)到數(shù)據(jù)的存儲與獲取。客戶端和OSD之間沒有中間服務(wù)器,中間件或總線。
當(dāng)一個OSD需要存儲數(shù)據(jù)時(無論客戶端是Ceph Block設(shè)備,Ceph對象網(wǎng)關(guān)或其他接口),從客戶端接收數(shù)據(jù)然后將數(shù)據(jù)存儲為對象。每一個對象相當(dāng)于文件系統(tǒng)中存放于如磁盤等存儲設(shè)備上的一個文件。

注: 一個對象的ID在整個集群中是唯一的,(全局唯一)而不僅僅是本地文件系統(tǒng)中的唯一。
Ceph OSD將所有數(shù)據(jù)作為對象存儲在扁平結(jié)構(gòu)的命名空間中(例如,沒有目錄層次結(jié)構(gòu))。對象在集群范圍內(nèi)具有唯一的標(biāo)識、二進(jìn)制數(shù)據(jù)、以及由一組名稱/值的鍵值對組成的元數(shù)據(jù)。而這些語義完全取決于Ceph的客戶端。例如,Ceph塊設(shè)備將塊設(shè)備鏡像映射到集群中存儲的一系列對象上。

注: 由唯一ID、數(shù)據(jù)、名稱/值構(gòu)成鍵值對的元數(shù)據(jù)組成的對象可以表示結(jié)構(gòu)化和非結(jié)構(gòu)化數(shù)據(jù),以及前沿新的數(shù)據(jù)存儲接口或者原始老舊的數(shù)據(jù)存儲接口。
第2章 存儲集群架構(gòu)
為了有效的實(shí)現(xiàn)無限可擴(kuò)展性、高可用性以及服務(wù)性能,Ceph存儲集群可以包含大量的Ceph節(jié)點(diǎn)。每個節(jié)點(diǎn)利用商業(yè)硬件以及智能的Ceph守護(hù)進(jìn)程實(shí)現(xiàn)彼此之間的通信:
存儲和檢索數(shù)據(jù)
數(shù)據(jù)復(fù)制
監(jiān)控并報告集群運(yùn)行狀況(心跳)
動態(tài)的重新分布數(shù)據(jù)(回填)
確保數(shù)據(jù)完整性(清理及校驗(yàn))
失敗恢復(fù)
對于讀寫數(shù)據(jù)的Ceph客戶端接口來說,Ceph存儲集群看起來就像一個存儲數(shù)據(jù)的簡單存儲池。然而,存儲集群背后卻是對客戶端接口完全透明的方式并且會執(zhí)行許多復(fù)雜的操作。Ceph客戶端和Ceph OSD都使用CRUSH算法(可控的、可擴(kuò)展的、分布式的副本數(shù)據(jù)放置算法),后面的章節(jié)會詳細(xì)講解CRUSH算法。
2.1 存儲池
Ceph存儲集群通過‘存儲池’這一邏輯劃分的概念對數(shù)據(jù)對象進(jìn)行存儲。可以為特定類型的數(shù)據(jù)創(chuàng)建存儲池,比如塊設(shè)備、對象網(wǎng)關(guān),亦或僅僅是為了將一組用戶與另一組用戶分開。
從Ceph客戶端來看,存儲集群非常簡單。當(dāng)有Ceph客戶端想讀寫數(shù)據(jù)時(例如,會調(diào)用I/O上下文),客戶端總是會連接到存儲集群中的一個存儲池上。客戶端指定存儲池名稱、用戶以及密鑰,所以存儲池會充當(dāng)邏輯劃分的角色,這一角色使得對數(shù)據(jù)對象訪問進(jìn)行控制。
實(shí)際上,存儲池不只是存儲對象數(shù)據(jù)的邏輯劃分,它還扮演著Ceph存儲集群是如何分布及存儲數(shù)據(jù)的角色,當(dāng)然了,這些復(fù)雜的操作對客戶端來說也是透明的。Ceph存儲池定義了:
存儲池類型:在以前的老版本中,一個存儲池只是簡單的維護(hù)對象的多個深拷貝。而現(xiàn)在,Ceph能夠維護(hù)一個對象的多個副本,或者能夠使用糾刪碼。正因?yàn)楸WC數(shù)據(jù)持久化的2種方法(副本方式與糾刪碼方式)存在差異,所以Ceph 支持存儲池類型。存儲池類型對于客戶端也是透明的。
PG:在EB規(guī)模的存儲集群中,一個Ceph存儲池可能會存儲數(shù)百萬或更多的數(shù)據(jù)對象。因?yàn)镃eph必須處理數(shù)據(jù)持久化(副本或糾刪碼數(shù)據(jù)塊)、清理校驗(yàn)、復(fù)制、重新再平衡以及數(shù)據(jù)恢復(fù),因此在每個對象基礎(chǔ)上的管理就會出現(xiàn)擴(kuò)展性和性能上的瓶頸。Ceph通過散列存儲池到PG的方式來解決這個瓶頸問題。CRUSH則分配每一個對象到指定的PG中,每個PG再到一組OSD中。
CRUSH規(guī)則集:Ceph中,高可用、持久化能力以及性能是非常重要的。CRUSH算法計算用于存儲對象的PG,同時也用于計算出PG的OSD Acting Set
譯者注:acting set即為活躍的osd集合,集合中第一個編號的osd即為主primary OSD。
CRUSH也扮演著其他重要角色:即CRUSH可以識別故障域和性能域(例如,存儲介質(zhì)類型、nodes, racks, rows等等)。CRUSH使得客戶端可以跨故障域(rooms, racks, rows等等)完成數(shù)據(jù)的寫入以便當(dāng)節(jié)點(diǎn)出現(xiàn)粒度比較大的問題時(例如,rack出問題)集群仍然可以以降級的狀態(tài)提供服務(wù)直至集群狀態(tài)恢復(fù)。CRUSH也可使客戶端能夠?qū)?shù)據(jù)寫入特定類型的硬件中(性能域),例如SSD或具有SSD日志的硬盤驅(qū)動器,亦或具有與數(shù)據(jù)驅(qū)動相同驅(qū)動的日志硬盤驅(qū)動器。對于存儲池來說,CRUSH規(guī)則集決定了故障域以及性能域。
數(shù)據(jù)持久化方式:在EB規(guī)模的存儲集群中,硬件故障因?yàn)榭深A(yù)期所以一般并不算異常。當(dāng)使用數(shù)據(jù)對象表示較大粒度的存儲接口時(例如塊設(shè)備),對于這種大粒度存儲接口來說,對象的丟失(不管是1個還是多個)都可能破壞數(shù)據(jù)的完整性進(jìn)而導(dǎo)致數(shù)據(jù)不可用。因此,數(shù)據(jù)丟失是不可容忍也是不能接受的。Ceph提供了2種持久化方式:第1種為副本存儲池方式,這種方式將多份相同內(nèi)容的數(shù)據(jù)對象通過CRUSH進(jìn)行故障域的隔離來存儲到不同的節(jié)點(diǎn)上(比如將對象分別存儲在硬件相互隔離的不同節(jié)點(diǎn)上),這樣即使硬件問題也不會對數(shù)據(jù)的持久化能力產(chǎn)生什么大的影響;第2種為糾刪碼存儲池方式,這種方式將對象存儲到K+M 個塊中,其中K表示數(shù)據(jù)塊,M 表示編碼塊。K+M的和表示總的OSD數(shù)量,可以支持最多同時有M 個OSD出現(xiàn)問題,數(shù)據(jù)也不會丟失。
從客戶端角度來看,Ceph對外呈現(xiàn)顯得優(yōu)雅而簡單。客戶端只需要讀取或?qū)懭霐?shù)據(jù)到存儲池。但是,存儲池在數(shù)據(jù)持久化,性能以及高可用方面發(fā)揮著重要的作用。
2.2 身份認(rèn)證
為了識別用戶并防止中間人攻擊,Ceph提供了cephx認(rèn)證系統(tǒng)來驗(yàn)證用戶和守護(hù)進(jìn)程。
注: Cephx協(xié)議并不處理傳輸中的數(shù)據(jù)加密(例如SSL/TLS)也不處理靜態(tài)數(shù)據(jù)加密。
Cephx使用共享的密鑰進(jìn)行認(rèn)證,這也意味著客戶端和mon都會有客戶端密鑰副本。認(rèn)證協(xié)議也就是雙方都能夠向?qū)Ψ阶C明他們擁有密鑰的副本,而不會實(shí)際泄露密鑰。這種方式提供了相互認(rèn)證的機(jī)制,意味著集群確信用戶擁有密鑰以及用戶確信集群擁有密鑰的副本。
2.3 PG(s)
Ceph將存儲池分片處理成在集群中均勻且偽隨機(jī)分布的PG。CRUSH算法將每個對象分配到一個指定的PG中,并且將每個PG分配到對應(yīng)的Acting Set集合中—也就是在Ceph客戶端和存儲對象副本的OSD之間創(chuàng)建一個間接層。如果Ceph客戶端直接就能知道對象存放到具體的哪個OSD中的話,那么Ceph客戶端和Ceph OSD之間耦合性就太強(qiáng)了。
相反的,CRUSH算法會動態(tài)的將對象分配到PG中,然后再將PG分配到一組Ceph的OSD中。有了這個間接層之后,當(dāng)新Ceph OSD加入或者Ceph OSD出現(xiàn)問題時,Ceph存儲集群就可以動態(tài)的進(jìn)行數(shù)據(jù)再平衡。通過在數(shù)百到數(shù)千個放置組的環(huán)境中管理數(shù)百萬個對象,Ceph存儲集群可以高效地增長和收縮以及從故障中恢復(fù)。
下面的圖描述了CRUSH是如何將對象分配到PG中,以及PG分配到OSD中的。?

相對整體集群規(guī)模來說,如果存儲池設(shè)置的PG較少,那么在每個PG上Ceph將會存儲大量的數(shù)據(jù);如果存儲池設(shè)置的PG過大,那么Ceph OSD將會消耗更多的CPU與內(nèi)存,不管哪一種情況都不會有較好的處理性能。所以,為每個存儲池設(shè)置適當(dāng)數(shù)量的PG,以及分配給集群中每個OSD的PG數(shù)量的上限對Ceph性能至關(guān)重要。
譯者注: PG是對象的集合, 在同一個集合里的對象放置規(guī)則都一樣(比如同一集合中的對象統(tǒng)一都存儲到osd.1、osd.5、osd.8這幾臺機(jī)器中);同時,一個對象只能屬于一個PG,而一個PG又對應(yīng)于所放置的OSD列表;另外就是每個OSD上一般會分布很多個PG。
2.4 CRUSH
Ceph會將CRUSH規(guī)則集分配給存儲池。當(dāng)Ceph客戶端存儲或檢索存儲池中的數(shù)據(jù)時,Ceph會自動識別CRUSH規(guī)則集、以及存儲和檢索數(shù)據(jù)這一規(guī)則中的頂級bucket。當(dāng)Ceph處理CRUSH規(guī)則時,它會識別出包含某個PG的主OSD,這樣就可以使客戶端直接與主OSD進(jìn)行連接進(jìn)行數(shù)據(jù)的讀寫。
為了將PG映射到OSD上,CRUSH 映射關(guān)系定義了bucket類型的層級列表(例如在CRUSH映射關(guān)系中的types以下部分)。創(chuàng)建bucket層級結(jié)構(gòu)的目的是通過其故障域和(或)性能域(例如驅(qū)動器類型、hosts、chassis、racks、pdu、pods、rows、rooms、data centers)來隔離葉子節(jié)點(diǎn)。
除了代表OSD的葉子節(jié)點(diǎn)之外,層次結(jié)構(gòu)的其余部分可以是任意的,如果默認(rèn)類型不符合你的要求,可以根據(jù)自己的需要來定義它。CRUSH支持一個有向無環(huán)圖的拓?fù)浣Y(jié)構(gòu),它可以用來模擬你的Ceph OSD節(jié)點(diǎn)在層級結(jié)構(gòu)中的分布情況。?
因此,可以在單個CRUSH映射關(guān)系中支持具有多個Root節(jié)點(diǎn)的多個層級結(jié)構(gòu)。例如,可以創(chuàng)建SSD的層級結(jié)構(gòu)、使用SSD日志的硬盤層級結(jié)構(gòu)等等。
譯者注: CRUSH的目的很明確, 就是一個PG如何與OSD建立起對應(yīng)的關(guān)系。
2.5 I/O操作
Ceph客戶端從Ceph mon獲取‘集群映射關(guān)系Cluster map,然后對存儲池中的對象執(zhí)行I/O操作。對于Ceph如何將數(shù)據(jù)存于目標(biāo)中來說,存儲池的CRUSH規(guī)則集和PG數(shù)的設(shè)置起主要的作用。擁有最新的集群映射關(guān)系,客戶端就會知道集群中所有的mon和OSD的信息。但是,客戶端并不知道對象具體的存儲位置(不知道對象具體存在哪個OSD上)。
對于客戶端來說,需要的輸入?yún)?shù)僅僅是對象ID和存儲池名稱。邏輯上也比較簡單:Ceph將數(shù)據(jù)存儲在指定名稱的存儲池中(例如存儲池名稱為livepool)。當(dāng)客戶端想要存儲一個對象時(比如對象名叫 “john”、“paul”、'george”、 “ringo”等),客戶端則會以對象名、根據(jù)對象名信息計算的hash碼、存儲池中的PG數(shù)、以及存儲池名稱這些信息作為輸入?yún)?shù),然后CRUSH(可控的、可擴(kuò)展的、分布式的副本數(shù)據(jù)放置算法)就會計算出PG的ID(PG_ID)及PG對應(yīng)的主OSD信息。
譯者注:根據(jù)設(shè)置的副本數(shù)(比如3副本)則計算出的列表如(osd.1、osd.3、osd.8), 這里的第一個osd.1就是主OSD。
Ceph客戶端經(jīng)過以下步驟來計算出PG ID信息。
客戶端輸入存儲池ID以及對象ID(例如,存儲池pool=”liverpool”, 對象ID=”john”)。
CRUSH獲取對象ID后對其進(jìn)行HASH編碼。
CRUSH根據(jù)上一步的HASH編碼與PG總數(shù)求模后得到PG的ID。(譯者注:例如HASH編碼后為186,而PG總數(shù)為128,則求模得58,所以這個對象會存儲在PG_58中;另外這也可以看出PG數(shù)對存儲的影響,因?yàn)樯婕暗綄ο笈cPG的映射關(guān)系,所以輕易不要調(diào)整PG數(shù))
CRUSH計算對應(yīng)PG ID的主OSD。
客戶端根據(jù)存儲池名稱得到存儲池ID(例如”liverpool”=4)。
客戶端將PG ID與存儲池ID拼接(例如?4.58)
客戶端直接與Activtin Set集合中的主OSD通信,來執(zhí)行對象的IO操作(例如,寫入、讀取、刪除等)。
譯者注: Pool的名稱與ID(ID=4,存儲池名稱為default.rgw.log)。

Ceph存儲集群的拓?fù)浜蜖顟B(tài)在會話(I/O上下文)期間相對比較穩(wěn)定。與客戶端在每個讀/寫操作的會話上查詢存儲相比,Ceph客戶端計算對象存儲位置的速度要更快些。CRUSH算法不但能使客戶端可以計算出對象應(yīng)當(dāng)存儲的位置,同時也使得客戶端可以和Acting Set集合中的主OSD直接交互來實(shí)現(xiàn)對象的存儲與檢索。由于EB規(guī)模的存儲集群一般會有數(shù)千個OSD存儲節(jié)點(diǎn),所以客戶端與Ceph OSD之間的網(wǎng)絡(luò)交互并不是什么大的問題。即使集群狀態(tài)發(fā)生變化,客戶端也可以通過Ceph mon查詢到更新的集群映射關(guān)系。
2.5.1 副本I/O
和Ceph客戶端一樣,Ceph OSD也是通過與Ceph mon交互來獲取到最新的集群映射關(guān)系。Ceph OSD也使用CRUSH算法,但是用這個算法是用來計算對象的副本應(yīng)該存儲在什么位置(譯者注: 客戶端用CRUSH是用來找主OSD以及計算出Acting Set列表,而OSD用CRUSH則是主OSD定位對應(yīng)的副本是誰)。
在典型的寫操作場景下,Ceph客戶端使用CRUSH算法計算對象所在的PG ID以及Acting Set列表中的主OSD,當(dāng)客戶端將對象寫到主OSD時,主OSD會查看這個對象應(yīng)該存儲的副本個數(shù)(例如,osd_pool_default_size = n),然后主OSD根據(jù)對象ID、存儲池名稱、集群映射關(guān)系這些信息再根據(jù)CRUSH算法來計算出Acting Set列表中的從屬OSD(譯者注: 除列表中第一個OSD外,其它的都是從屬OSD)。
主OSD將對象寫入從屬OSD中,當(dāng)主OSD收到從屬OSD回復(fù)的ACK確認(rèn)并且主OSD自身也完成了寫操作后,主OSD才會給Ceph客戶端回復(fù)真正寫入成功的ACK確認(rèn)。

通過有代表性的Ceph客戶端(主OSD)執(zhí)行數(shù)據(jù)復(fù)制的能力,Ceph OSD守護(hù)進(jìn)程相對的減輕了Ceph客戶端的這一職責(zé),同時確保了數(shù)據(jù)高可用以及安全性。
注:?比較典型的就是主OSD和從屬OSD在部署時會將故障域進(jìn)行隔離(比如不同時配置到一個rack上或一個row上,亦或是同一個node上)。CRUSH計算從屬OSD的ID也會考慮故障域信息。
2.5.2 糾刪碼I/O
糾刪碼實(shí)際上是一種前向錯誤糾正編碼,這種編碼會將K個數(shù)據(jù)塊通過補(bǔ)充N個編碼塊的方式,將原始數(shù)據(jù)擴(kuò)展為更長的消息編碼,以便當(dāng)N個數(shù)據(jù)塊出現(xiàn)問題時數(shù)據(jù)依舊不會丟失。隨著時間的推移,開發(fā)了不同的糾刪編碼算法,其中最早和最常用的算法之一是Reed-Solomon算法。
可以通過等式 N = K + M 對這一算法進(jìn)行理解,等式中 K 表示數(shù)據(jù)塊的個數(shù),M 代表了編碼塊的個數(shù),而 N 則是在?糾刪編碼?過程中創(chuàng)建的總的塊的個數(shù)。值 M 可以簡化為 N – K ,也就是說在計算原始的K個數(shù)據(jù)塊時 N – K 個冗余塊也一并需要計算出來。這種方法保證只要N個塊中的K有效就可以訪問所有原始數(shù)據(jù)。換句話說,即使有 N – K 個塊出現(xiàn)了故障,對外提供服務(wù)的數(shù)據(jù)仍舊是沒有問題的。
例如配置(N=16,K=10)或者糾刪編碼 10/16,10個基本的塊(K)中會有額外補(bǔ)充的6個塊( M = K-N, 如16-10 = 6 ) 。這16個塊(N)可能對應(yīng)16個OSD。即使有6個OSD出現(xiàn)問題,原始文件也可以從這10個已經(jīng)驗(yàn)證的數(shù)據(jù)塊中重建恢復(fù)。這就意味著不會有任何的數(shù)據(jù)丟失,因此糾刪碼也具備比較高的容錯能力。
和副本存儲池類似,糾刪碼存儲池也是由up set列表中的主OSD來接收所有的寫操作。在副本存儲池中,Ceph對PG中的每個對象在從屬OSD上都會有一份一樣的數(shù)據(jù)對象;而對于糾刪碼存儲池來說,可能略有不同。每個糾刪碼存儲池都會以 K+M 個塊來存儲每一個對象。
對象(的數(shù)據(jù)內(nèi)容)會被切分成 K 個數(shù)據(jù)塊以及 M個編碼塊。糾刪碼存儲池創(chuàng)建時也需要配置成 K+M 的大小(size)以便每個塊都可以存儲到Activtin Set列表中的每個OSD上。對象的屬性存儲這些塊的等級。主OSD負(fù)責(zé)數(shù)據(jù)劃分到 K+M 個塊的糾刪編碼以及將這些編碼信息發(fā)送到其它的OSD上。同時主OSD也會維護(hù)PG的權(quán)威日志(譯者注: 權(quán)威日志實(shí)際是一種進(jìn)度控制機(jī)制,尤其當(dāng)某些節(jié)點(diǎn)出現(xiàn)問題時,可以根據(jù)權(quán)威日志進(jìn)行數(shù)據(jù)的恢復(fù))。
例如,使用5個OSD (K + M = 5)?創(chuàng)建糾刪碼存儲池,支持其中2個?(M = 2)?塊的數(shù)據(jù)丟失。
將對象寫入糾刪碼存儲池中的時候(比如對象名叫 NYAN,內(nèi)容為 ABCDEFGHI )糾刪碼計算函數(shù)會將對象的內(nèi)容按長度平分成3個塊(即,分成K個數(shù)據(jù)塊),第一個塊內(nèi)容為 ABC , 第二個塊內(nèi)容為DEF , 第三個塊內(nèi)容為 GHI , 如果塊內(nèi)長度不是 K 的倍數(shù),那么平分后最后的一塊所剩余的空位就會進(jìn)行填充以使其長度為K(比如內(nèi)容串為ABCDEFGHIJ,則3個數(shù)據(jù)塊內(nèi)容依次為ABCD、EFGH、IJ..,最后的IJ長度不夠就會填充);除了將內(nèi)容按K切分外, 糾刪碼函數(shù)也要創(chuàng)建另外2個編碼塊,即第4個塊內(nèi)容為 XYZ ,第5個塊內(nèi)容為 GQC 。
這里的每一個塊內(nèi)容都對應(yīng)Action Set列表中的一個OSD。這些塊有相同的名稱都叫 NYAN , 但塊存在不同的OSD中。除了名稱之外,數(shù)據(jù)塊創(chuàng)建的對應(yīng)序號需要存儲在對象的屬性中( shard_t ) 。包括 ABC 內(nèi)容的第一個塊存儲在 OSD5 上,而包括 YXY 內(nèi)容的第4個塊則存儲在 OSD3 上。

譯者注: 注意上圖中,5個塊的名稱都叫NYAN,每個塊的內(nèi)容為K個均分的內(nèi)容, 同時被切分后的每個塊都有一個唯一序號shard, 每個塊都對應(yīng)不同的OSD,即塊按HOST進(jìn)行故障域隔離。
譯者注: ?比如以下配置及圖例中,K=4, M=2 并且以rack作為故障域)

如果從糾刪碼存儲池中讀取對象 NYAN, 解碼函數(shù)需要讀取3個塊: 包括ABC 的第一個塊, 包括GHI 的第3個塊以及包括YXY 的第4個塊;然后重構(gòu)出對象的內(nèi)容ABCDEFGHI 。解碼函數(shù)來通知第2個塊和第5個塊缺失(一般稱為糾刪或擦寫)。
可在這2個缺失的塊中,第5個塊缺失可能因?yàn)镺SD4 狀態(tài)是OUT而讀不到,只要讀到3個塊可讀的話,解碼函數(shù)就可以被調(diào)用:因?yàn)镺SD2對應(yīng)的是最慢的塊,所以讀取時排除掉不在考慮之內(nèi)。
將數(shù)據(jù)拆分成不同的塊是獨(dú)立于對象放置規(guī)則的。CRUSH規(guī)則集和糾刪碼存儲池配置決定了塊在OSD上的放置。例如,在配置中如果使用lrc(局部可修復(fù)編碼)插件來創(chuàng)建額外塊的話,那么恢復(fù)數(shù)據(jù)的話則需要更少的OSD。
例如lrc配置信息: K=4、M=2、L=3 中,使用jerasure插件庫來創(chuàng)建6個塊(K+M),但局部值(L=3 )則要求需要再創(chuàng)建2個局部塊。額外創(chuàng)建的局部塊個數(shù)可以通過(K+M)/L 來計算得出。如果0號塊的OSD出現(xiàn)問題,那么這個塊的數(shù)據(jù)可以通過塊1,塊2以及第一個局部塊進(jìn)行恢復(fù)。在這個例子中,恢復(fù)也只需要3個塊而不是5個塊。關(guān)于CRUSH、糾刪碼配置、以及插件的內(nèi)容,可以參考存儲策略指南。
注:?糾刪碼存儲池的對象映射是失效的,不能設(shè)置為有效狀態(tài)。關(guān)于對象映射的更多內(nèi)容,可以參考對象映射章節(jié)。
注:?糾刪碼存儲池目前共支持RADOS網(wǎng)關(guān)(RGW),對于RADOS的塊設(shè)備(RBD)目前還不支持。
2.6 自管理的內(nèi)部操作
Ceph集群也會自動的執(zhí)行一些自身狀態(tài)相關(guān)的監(jiān)控與管理工作。例如,Ceph的OSD可以檢查集群的健康狀態(tài)并將結(jié)果上報給后端的Ceph mon;再比如,通過CRUSH算法將對象映射到PG上,再將PG映射到具體的OSD上;同時,Ceph OSD也通過CRUSH算法對OSD的故障等問題進(jìn)行自動的數(shù)據(jù)再平衡以及數(shù)據(jù)恢復(fù)。以下部分我們將介紹Ceph執(zhí)行的一些操作。
2.6.1 心跳
Ceph OSD加入到集群中并且將其狀態(tài)上報到Ceph mon。在底層實(shí)現(xiàn)上,Ceph OSD的狀態(tài)就是up或?yàn)閐own ,這一狀態(tài)反映的就是OSD是否運(yùn)行并為Ceph客戶端的請求提供服務(wù)。如果Ceph OSD在集群中的狀態(tài)是donw且為in ,那么表明此OSD是有問題不能提供服務(wù)的;如果Ceph OSD并沒有運(yùn)行(比如服務(wù)crash掉了),那么這個Ceph OSD也不能上報給Ceph mon其自身狀態(tài)為Down 。
Ceph mon會定期的ping 這些OSD以此來確信這些OSD是否仍在運(yùn)行。當(dāng)然了,Ceph也提供了更多的機(jī)制,比如使Ceph OSD可以評判與之關(guān)聯(lián)的OSD是否狀態(tài)為down(譯者注:比如在副本OSD間相互ping狀態(tài)的關(guān)系,沒有副本關(guān)系的話,OSD之間不會建立連接亦即更不會ping彼此),以及更新Ceph的集群映射關(guān)系并上報給Ceph mon。由于OSD分擔(dān)了部分工作,所以對于Ceph mon來說,工作內(nèi)容相對要輕量很多。
2.6.2 同步
Ceph OSD守護(hù)進(jìn)程執(zhí)行同步,這里的同步指的是將存儲放置組(PG)的所有OSD中對象狀態(tài)(包括元數(shù)據(jù)信息)達(dá)到一致的過程。同步問題通常都會自行解決無需人為的干預(yù)。
注:?即使Ceph mon對于OSD存儲PG的狀態(tài)達(dá)成一致,這也并不意味著PG擁有最新的內(nèi)容。
當(dāng)Ceph存儲PG到OSD的acting set列表中的時候,會將它們分別標(biāo)記為主,從等等。慣例上,Acting set列表中的第一個是主OSD,主OSD也負(fù)責(zé)協(xié)調(diào)組內(nèi)的PG進(jìn)行同步操作,這里的主OSD也是唯一?接收客戶端的寫入對象到給定PG請求的OSD。
當(dāng)一系列的OSD負(fù)責(zé)一個放置組PG,則這一系列的OSD,我們稱它們?yōu)橐粋€Acting Set。Acting Set可能指的是當(dāng)前負(fù)責(zé)放置組的Ceph OSD守護(hù)進(jìn)程或者某個有效期內(nèi),負(fù)責(zé)特定放置組的OSD守護(hù)進(jìn)程。
Acting Set中的部分Ceph OSD可能不會一直是up 狀態(tài)。當(dāng)Acting Set中的OSD狀態(tài)是up 狀態(tài)時,那么這個OSD也是Up Set中的成員。相對Acting Set來說,Up Set是非常重要的,因?yàn)楫?dāng)OSD失敗時,Ceph可以將PG重新映射到其他Ceph OSD上。
注:?對于PG包括osd.25、osd.32、osd.61的Acting Set列表,列表中第一個OSD即osd.25 是主OSD。如果主OSD失敗,那么從屬OSD 即osd.32 就會成為新的主OSD,同時原主osd.25 也會從Up Set列表中刪除。
2.6.3 數(shù)據(jù)再平衡與恢復(fù)
當(dāng)我們向Ceph存儲集群中新增加Ceph OSD的時候,集群映射關(guān)系隨著新增加的OSD同時也會更新。因此,由于這一變化改變了計算CRUSH時提供的輸入?yún)?shù),所以也就間接的改變了對象的放置位置。CRUSH算法是偽隨機(jī)的,但會均勻的放置數(shù)據(jù)。所以集群中新增加一臺OSD時,也只會有一小部分的數(shù)據(jù)發(fā)生遷移。一般遷移的數(shù)據(jù)量是集群總數(shù)據(jù)量與OSD數(shù)量的比值(例如,在有50個OSD的集群中,當(dāng)新增加一臺OSD時也只有1/50 或者2%的數(shù)據(jù)受到遷移影響)。
下面的圖示描述了部分的PG(非全部PG)從已有的OSD 1,OSD 2上遷移到新OSD 3上達(dá)到數(shù)據(jù)再平衡的過程(因?yàn)閷Υ笮图旱挠绊懸〉枚啵赃^程相對粗略一些)。即使在再平衡過程中,CRUSH也是穩(wěn)定的。大部分的PG仍然保留著原始的配置,由于新增加了OSD,所以每個OSD都會增加一些(可用的)容量,因此在重新平衡完成后,新的OSD上也不會出現(xiàn)負(fù)載峰值的情況。

2.6.4 校驗(yàn)(或擦除)
作為Ceph中維護(hù)數(shù)據(jù)一致性以及整潔性的部分,Ceph OSD 守護(hù)進(jìn)程也可以完成PG內(nèi)的對象清理工作,意思就是Ceph OSD守護(hù)進(jìn)程比較副本間PG內(nèi)的對象元數(shù)據(jù)信息。校驗(yàn)/擦除(通常是天級別的調(diào)度策略)捕獲異常或文件系統(tǒng)的一些錯誤。同時,Ceph OSD守護(hù)進(jìn)程也可以進(jìn)行更深層次的比較(對象數(shù)據(jù)本身的按位比較),而這種深層次的比較(可以發(fā)現(xiàn)驅(qū)動盤上壞的扇區(qū))一般是周級別的調(diào)度策略。
2.7 高可用
除了通過CRUSH算法實(shí)現(xiàn)高可擴(kuò)展性外,Ceph也需要支持高可用性。這就意味著即使集群處于降級狀態(tài)或某個Ceph mon出現(xiàn)問題情況下(譯者注:這里出問題的mon個數(shù)不能超過mon總數(shù)的一半,否則集群會阻塞所有操作),客戶端仍舊可以進(jìn)行數(shù)據(jù)的讀寫。
2.7.1 數(shù)據(jù)副本
在副本存儲池中,Ceph需要對象的多個副本在降級狀態(tài)下運(yùn)行。理想情況下,即使Acting Set中的一個OSD出現(xiàn)問題,Ceph存儲集群也可以支持客戶端讀寫操作。基于此,Ceph默認(rèn)也是一個對象保持3副本的設(shè)置,寫操作則要求至少2個副本為clean狀態(tài)(譯者注: 具體設(shè)置多少個副本為clena才支持寫操作,這要依賴于設(shè)置存儲池時的配置,例如,在ceph osd dump | grep pool輸出中的replicated size 3 min_size 2,這里的2就是至少有多少個副本為clean,在這個存儲池上的寫操作才被支持,而這個值是可以再更新的)。
如果有2個OSD出現(xiàn)問題,Ceph仍然可以保留數(shù)據(jù)不會丟失,但是就不能進(jìn)行寫操作了。
在糾刪碼存儲池中,Ceph需要多個OSD來存儲對象分割后的塊以便在降級狀態(tài)仍然可以操作。與副本存儲池類似,理想情況下,在降級狀態(tài)下糾刪碼存儲池也支持Ceph客戶端進(jìn)行讀寫操作。基于此,我們則建議設(shè)置K+M=5 通過5個OSD來存儲塊信息,同時設(shè)置M=2 以保證即使2個OSD出現(xiàn)問題也可以根據(jù)剩余的OSD進(jìn)行數(shù)據(jù)的恢復(fù)重建。
2.7.2 Mon集群
在客戶端進(jìn)行數(shù)據(jù)讀寫之前,客戶端必須從Ceph mon端獲取最新的集群映射關(guān)系。一個Ceph存儲集群可以與一臺mon進(jìn)行通信發(fā)起操作,然而這就存在單點(diǎn)問題(例如這個單點(diǎn)的mon出現(xiàn)問題,Ceph客戶端則不能進(jìn)行數(shù)據(jù)的讀寫)。
為了提供服務(wù)的可靠性以及容錯性,Ceph支持mon組成集群方式提供服務(wù)。在mon集群中,延遲和其他的故障可能導(dǎo)致一個或多個mon落后于集群當(dāng)前的狀態(tài)。基于此,Ceph必須在集群狀態(tài)的各種mon實(shí)例之間達(dá)成一致。對于集群當(dāng)前的狀態(tài),Ceph也總是使用大多數(shù)的mon(例如: 1、2:3、3:5、4:6等等)或者Paxos算法進(jìn)行一致性確認(rèn)。同時,mon集群內(nèi)機(jī)器間也需要NTP時間服務(wù)防止時鐘漂移。
2.7.3 CephX
Cephx 認(rèn)證協(xié)議的操作方式與Kerberos類似。用戶、角色調(diào)用Ceph客戶端來與mon交互,不像Kerberos,每一個monitor都可以對用戶進(jìn)行認(rèn)證并分發(fā)密鑰,所以使用cephx 不存在單點(diǎn)問題或瓶頸。mon返回類似于Kerberos的包含會話密鑰信息的結(jié)構(gòu)以便調(diào)用方可以根據(jù)密鑰對接Ceph的所提供的服務(wù)。這里的會話密鑰本身使用了用戶的永久密鑰進(jìn)行加密,因此只有用戶自已才可以從Ceph mon請求服務(wù)。
客戶端使用會話密鑰從monitor處獲取想要的服務(wù),mon則通過認(rèn)證使得客戶端有權(quán)限對接OSD來完成數(shù)據(jù)交互。Ceph mon和OSD共享一個秘鑰,因此客戶端可以使用mon提供的憑證與群集中的任何OSD或元數(shù)據(jù)服務(wù)器進(jìn)行交互。和Kerberos類似,cephx 憑證也有超時時間,所以并不能使用一個超時的憑證偷偷的對集群進(jìn)行攻擊。只要用戶的密鑰在到期前不泄露的話,這種身份認(rèn)證的形式可以防止攻擊者以其他用戶的身份創(chuàng)建偽造消息或更改其他用戶的合法消息訪問通信介質(zhì)。
如果使用Cephx 認(rèn)證,管理員必須先設(shè)置用戶。在下面的圖示中,client.admin 用戶通過命令行執(zhí)行ceph auth get-or-create-key 命令,創(chuàng)建用戶以及密鑰。Ceph的auth 子系統(tǒng)生成用戶名以及密鑰,并將其存于mon中以及將用戶名與密鑰返回給調(diào)用命令的client.admin 用戶。這也就意味著客戶端與mon共享同一個密鑰。
注: client.admin 用戶必須以安全的方式向用戶提供用戶ID和密鑰。

第3章 客戶端架構(gòu)
Ceph客戶端在數(shù)據(jù)存儲的接口方面還是存在比較大的差異的。Ceph的塊設(shè)備提供了可以像掛載本地物理驅(qū)動盤一樣的塊存儲,而Ceph對象網(wǎng)關(guān)則通過用戶的管理提供了兼容S3與Swift的Restful對象存儲接口。而對于這些接口,都是使用的RADOS(可靠且自動分布式的對象存儲)協(xié)議與Ceph存儲集群進(jìn)行的交互;同時這些接口也都有一些相同的基本前提:
Ceph配置文件,或集群名稱(通常為ceph?)與mon地址
存儲池名稱
用戶名以及密鑰的路徑
Ceph客戶傾向于遵循一些類似的模式,例如對象的監(jiān)視-通知以及條帶化。下面大概介紹下Ceph客戶端里使用的RADOS,librados以及常見的模式。
3.1 本地協(xié)議與Librados
現(xiàn)代的應(yīng)用需要有異步通信能力簡單的對象存儲接口,Ceph存儲集群就有這個能力并提供簡單的接口。此接口提供了對集群直接、并行的對象存取。
存儲池操作
快照
讀、寫對象
– 創(chuàng)建或刪除
– 整個對象或字節(jié)范圍
– 追加或截斷創(chuàng)建/設(shè)置/獲取/刪除 XATTRs
創(chuàng)建/設(shè)置/獲取/刪除 K/V對
復(fù)合操作和雙重ack語義
3.2 對象的監(jiān)視與通知
Ceph客戶端可以為對象注冊持久的關(guān)注點(diǎn),并保持與主OSD的會話開啟。客戶端可以向所有觀察者發(fā)送通知消息和數(shù)據(jù),并在觀察者收到通知時接收通知。這使得客戶端可以使用任何對象作為同步/通信的通道。

3.3 獨(dú)占鎖
獨(dú)占鎖提供一種功能特性:任一客戶端可以對RBD中資源進(jìn)行’排它的’鎖定(如果有多個終端對同一RBD資源進(jìn)行操作時)。這有助于解決當(dāng)有多個客戶端嘗試寫入同一對象時發(fā)生沖突的場景。此功能基于前一節(jié)中介紹的對象的監(jiān)視與通知。因此,在寫入時,如果一個客戶端首先在對象上建立獨(dú)占鎖,那么其它的客戶端如果想寫入數(shù)據(jù)的話就需要在寫入前先檢查是否在對象上已經(jīng)放置了獨(dú)占鎖。
設(shè)置了這一特性的話,同一時刻只有一個客戶端能夠?qū)BD資源進(jìn)行修改,尤其像快照創(chuàng)建與刪除這種改變RBD內(nèi)部結(jié)構(gòu)的時候。這一特性對于失敗的客戶端也起到了一些保護(hù)的作用,例如,虛擬機(jī)沒有響應(yīng)了,然后在其他地方使用同一塊磁盤啟動它的副本,那么這個無響應(yīng)的虛擬機(jī)將在Ceph中被列入黑名單,并且無法破壞新的虛擬機(jī)中數(shù)據(jù)。
強(qiáng)制的獨(dú)占鎖功能特性默認(rèn)是不開啟的,但是可以在創(chuàng)建鏡象時顯示的通過加入–image-features參數(shù)來開啟這一特性,例如:
rbd -p mypool create myimage –size 102400 –image-features 5
這里的5是1與4的和值, 其中1使得分層特性生效,4使得獨(dú)占鎖特性生效。所以執(zhí)行上面這個命令后會創(chuàng)建100GB的RBD鏡象,同時既支持分層特性也支持獨(dú)占鎖特性。
強(qiáng)制的獨(dú)占鎖也是后面提到的對象索引映射使用的前提。如果沒有開啟強(qiáng)制的獨(dú)占鎖,那么對象索引映射也不會生效。
獨(dú)占鎖也為mirror這塊內(nèi)容做了不少的工作。
3.4 對象映射索引
對象映射索引也是一種功能特性,可以在客戶端寫入rbd映像時跟蹤RADOS對象是否已經(jīng)存在了。當(dāng)有寫入操作時,寫操作被轉(zhuǎn)義為RADOS對象中的偏移,如果對象映射索引功能開啟那么對于存在的RADOS對象就會被跟蹤到。所以當(dāng)對象已經(jīng)存在時我們就可以提前知道。對象映射索引保存在librbd客戶端機(jī)器內(nèi)存中,所以對于不存在的對象就省去了再去查詢OSD的這一步開銷。對象映射索引對于一些操作還是比較有利的,即:
調(diào)整大小
導(dǎo)出操作
復(fù)制操作
扁平化
刪除
讀取
縮小操作就像是對尾部對象的部分刪除。導(dǎo)出操作知道哪些對象被RADOS請求。復(fù)制操作知道哪些對象存在并需要復(fù)制。它不需要遍歷潛在的數(shù)百或數(shù)千個可能的對象。扁平化操作將所有父對象拷貝到克隆中,以便可以將克隆與父項(xiàng)分離,即可以刪除從子克隆到父快照的引用。因此,不是對所有潛在的對象,僅是對存在的對象進(jìn)行復(fù)制。
刪除操作僅刪除鏡像中存在的對象。讀取操作對于不存在的對象會直接跳過。因此,對于調(diào)整大小(僅縮小)、導(dǎo)出操作、復(fù)制操作、扁平化和刪除等操作,這些操作需要針對所有可能受到影響的RADOS對象(無論它們是否存在)發(fā)布操作。如果啟用對象映射索引特性的話,對象若不存在就不需要發(fā)布操作了。
例如,我們有一個RBD鏡象,有1TB的數(shù)據(jù)且比較稀疏,可能擁有數(shù)百或數(shù)千個RADOS對象。如果不開啟對象映射索引的話,執(zhí)行刪除操作則需要對每一個潛在的目標(biāo)對象發(fā)布刪除對象操作;但是如果開啟了這一特性,那么只需要對真正存在的對象發(fā)布一個刪除對象的操作就可以了。
對象映射索引對于克隆是比較有價值的(自身沒有實(shí)際對象但可以從父對象那獲取)。當(dāng)有一個克隆的鏡像時,克隆初始并沒有什么對象,所有對克隆對象的讀操作都會重定向到父對象中。開啟對象映射索引可以改善讀操作,首先對于克隆對象向OSD發(fā)布讀操作,如果讀失敗了,那么再向克隆對象的父對象發(fā)布讀操作。讀操作會直接忽略掉根本不存在的對象。
對象映射索引默認(rèn)是不開啟的,但是可以在創(chuàng)建鏡象時顯示的通過加入–image-features參數(shù)來開啟這一特性。同時獨(dú)占鎖?也是對象映射索引功能特性的使用前提。如果不開啟獨(dú)占鎖功能特性則對象映射索引也不會生效。創(chuàng)建鏡象時如果開啟對象映射索引,可以執(zhí)行:
rbd -p mypool create myimage –size 102400 –image-features 13
這里的13是1、4、8的和值, 其中1 使得分層特性生效,4 使得獨(dú)占鎖特性生效,8 使得對象映射索引特性生效。所以執(zhí)行上面這個命令后會創(chuàng)建100GB的RBD鏡象,同時既支持分層特性也支持獨(dú)占鎖特性和對象映射索引特性。
3.5 數(shù)據(jù)條帶化
存儲設(shè)備一般在吞吐量上都有限制,這就會影響到服務(wù)的性能和伸縮性。因此,存儲系統(tǒng)一般會提供條帶化方案來提高性能與吞吐能力(即,將有序的信息分割成多個區(qū)段后存儲到多個設(shè)備上)。關(guān)于條帶化最常見的就是RAID(譯者注: 磁盤陣列RAID,意為將多個磁盤組合成一個容量更大的磁盤組,利用單塊盤存儲的疊加效果來提升整個磁盤存儲冗余能力。采用這種方案后,將存儲的數(shù)據(jù)切割成許多個區(qū)段數(shù)據(jù),然后分別存放在各個硬盤上)。與Ceph中條帶化最相似的RAID類型就是RAID 0或’條帶化卷’。Ceph的條帶化提供了RAID 0級的吞吐能力以及n路RAID鏡像的可靠性和快速的數(shù)據(jù)恢復(fù)能力。
Ceph提供3種客戶端對接類型: Ceph塊設(shè)備(CephRBD)、Ceph文件系統(tǒng)(CephFS)、Ceph對象存儲(一般是Ceph RGW)。數(shù)據(jù)存儲方面,Ceph客戶端會將用戶提交的數(shù)據(jù)轉(zhuǎn)換為Ceph存儲集群內(nèi)部的格式存儲到集群中,在提供給用戶的接口上也是按照這3種類型完成的:塊設(shè)備鏡像、對象存儲的RESTful接口、以及CephFS系統(tǒng)目錄。
提示:?存儲在Ceph存儲集群中的對象自身并沒有條帶化。Ceph對象存儲,Ceph塊設(shè)備和Ceph文件系統(tǒng)將客戶端數(shù)據(jù)條帶化后存儲在Ceph集群內(nèi)的多個對象中。如果想充分發(fā)揮并行能力,使用librados庫直接將數(shù)據(jù)寫入到Ceph存儲集群的Ceph客戶端必須執(zhí)行條帶化(以及并行I/O)。
最簡單的Ceph條帶化格式即為條帶數(shù)量為1的單個對象。Ceph客戶端將條帶單元塊寫入到Ceph存儲集群對象中,直到對象達(dá)到其最大容量,然后再為額外的條帶化數(shù)據(jù)創(chuàng)建另一個對象。對于較小的塊設(shè)備鏡像、S3或Swift對象來說,這種簡單的條帶化方式可能就完全能夠滿足需求,然而,這種簡單的形式并沒有最大限度的利用Ceph在整個放置組中分布數(shù)據(jù)的能力,因此并不能有較大的性能提升。下面圖示描述了這種最簡單的條帶化方式:
?
譯者注: 例如每一個對象存儲上限是4M,同時每一個單元塊占1M,這時我們有一個8M大小的文件想進(jìn)行存儲,這樣前4M存儲在對象0中,后4M就創(chuàng)建另一個對象1來存儲。
如果可以預(yù)知存儲需求為較大的圖像,或較大的S3對象或Swift對象(例如視頻),若想有較大的讀寫性能提升,則可以通過將客戶端數(shù)據(jù)條帶化分割存儲到多個對象上。如果客戶端將條帶單元塊并行的寫入到對應(yīng)對象中,由于對象映射到不同的PG上進(jìn)而會映射到不同的OSD上,每個寫操作都以最大化速并行進(jìn)行,那么寫性能的提升是相當(dāng)明顯的。
如果完全只對一塊磁盤寫入操作的話,受限就比較多: 磁頭的移動(例如每次6ms的尋址時間開銷)、設(shè)備的帶寬(例如每秒最大100MB)。通過擴(kuò)展多個對象上的寫入(映射到不同的PG以及OSD上),Ceph不但可以降低每個驅(qū)動盤的尋址時間,同時也可以合并多個驅(qū)動盤的吞吐能力以獲取更快的讀寫速度。
注:?條帶化獨(dú)立于對象的副本。由于CRUSH跨OSD復(fù)制對象,所以條帶化也會自動完成復(fù)制。
在下面的圖示中,客戶端跨越對象集(對象集 1)來獲取條帶數(shù)據(jù)。對象集中由4個對象組成,第1個條帶單元塊是存儲在object 0中的stripe unit 0,第4個條帶單元塊是存儲在 object 3中的stripe unit 3。當(dāng)寫完第4個單元塊時,客戶端會判斷對象集是否已滿,如果沒有滿的話,客戶端繼續(xù)將條帶單元塊寫入第1個對象中(下圖中的object 0)。如果對象集已滿,那么客戶端就會創(chuàng)建一個新的對象集(下圖中的對象集 2),然后將第1個條帶單元塊(stripe unit 16)寫入到新對象集中的第1個對象中(下圖中的object 4)。

Ceph數(shù)據(jù)條帶化過程中,有3個比較重要的參數(shù)會對條帶化產(chǎn)生影響:
對象大小:Ceph存儲集群中可以配置對象大小的上限值(比如2M、4M等),對象大小也應(yīng)該足夠的大以便與條帶單元塊相適應(yīng),同時設(shè)置對象的大小也應(yīng)該是單元塊大小的倍數(shù)。Red Hat則建議對象大小比較合理的值是16MB。
條帶寬度:條帶化中的單元塊大小也是可配置的(例如64kb)。Ceph客戶端將寫入對象的數(shù)據(jù)劃分為相同大小的條帶單元塊(因?yàn)閷懭氲臄?shù)據(jù)不一定是單元塊的倍數(shù),所以最后剩余的一個單元塊可能大小與其它的不一樣)。條帶寬度應(yīng)該是對象大小的一個分?jǐn)?shù)(比如對象是4M,單元塊是1M,則一個對象能包含4個單元塊),以便對象可以包含更多條帶單元塊。(譯者注:條帶寬度也是指同時可以并發(fā)讀或?qū)懙臈l帶數(shù)量。一般這個數(shù)量等于RAID中的物理硬盤數(shù)量)
條帶數(shù)量:根據(jù)條帶數(shù)量,Ceph客戶端將一批條帶單元塊寫入到一系列對象中。這里的一系列對象也就是對象集。在Ceph客戶端寫入對象集中最后一個對象之后會返回到對象集中的第1個對象。
重要提示:?在服務(wù)上線生產(chǎn)環(huán)境前,最好對條帶化進(jìn)行性能上的測試,因?yàn)橐坏?shù)據(jù)寫入,就無法再更改條帶參數(shù)信息了。
一旦Ceph客戶端將條帶化數(shù)據(jù)映射到條帶單元塊上,進(jìn)而映射到對象上,在對象最終以文件形式存儲在磁盤上之前,Ceph的CRUSH算法會將對象映射到PG中,然后再將PG映射到OSD守護(hù)進(jìn)程中。
注:?由于客戶端寫入單個存儲池中,因此條帶化到對象中的所有數(shù)據(jù)都會映射到同一個存儲池的PG內(nèi)。所以也會使用相同的CRUSH映射關(guān)系以及相同的訪問控制策略。
譯者注:?在Ceph存儲中,涉及條帶化的主要是Order、stripe_unit和stripe_count這3個參數(shù)。由這3個參數(shù)確定了數(shù)據(jù)的寫入與存儲編排方式。默認(rèn)情況order是22,也即對象大小為4MB(2的22次方),strip_unit大小與對象大小一致(也是4M),strip_count為1(對象集中只有1個對象)。
第4章 加密相關(guān)
LUKS磁盤加密及帶來的好處:?在Linux系統(tǒng)中,可以使用LUKS方法對磁盤分區(qū)進(jìn)行加密,由于LUKS是對整個塊設(shè)備進(jìn)行加密,所以對于便攜式存儲能夠起到較好的數(shù)據(jù)保護(hù)作用。
可以使用Ceph-ansible工具創(chuàng)建加密的OSD存儲節(jié)點(diǎn),這樣可以對OSD上存儲的數(shù)據(jù)進(jìn)行保護(hù)。更詳細(xì)的內(nèi)容可以參考
如何使用ceph-ansible創(chuàng)建加密的磁盤分區(qū):?在OSD安裝過程中,ceph-ansible會調(diào)用ceph-disk工具來完成創(chuàng)建加密分區(qū)的工作。
除了數(shù)據(jù)和日志分區(qū)外(Ceph data和ceph journal),ceph-disk 工具也會創(chuàng)建一個小的密碼箱分區(qū)以及名稱為cephx client.osd-lockbox 的用戶。ceph密碼箱分區(qū)包含一個密鑰文件,client.osd-lockbox 用戶使用這個密鑰文件獲取LUKS私鑰,從而對ceph data和ceph journal分區(qū)進(jìn)行解密。
之后,Ceph-disk會再調(diào)用cryptsetup 工具為ceph data和ceph journal分區(qū)創(chuàng)建2個dm-crypt設(shè)備。其中dm-crypt設(shè)備使用ceph data和ceph journal的GUID作為標(biāo)識。
Ceph-ansible如何處理LUKS密鑰: Ceph-ansible工具將LUKS私鑰存儲在Ceph monitor監(jiān)視器的K/V存儲中。每個OSD都有自己的密鑰將存儲在dm-crypt設(shè)備上加密的OSD數(shù)據(jù)和日志進(jìn)行解密。加密分區(qū)在服務(wù)啟動時就自動的進(jìn)行了解密操作。
關(guān)注「開源Linux」加星標(biāo),提升IT技能
