當前位置:
首頁 > 科技 > Redhat Ceph存儲之「深入理解Ceph架構」

Redhat Ceph存儲之「深入理解Ceph架構」

本文由Ceph中國社區穆艷學翻譯、耿航校稿,英文原文出處: Red_Hat_Ceph_Storage-2-Architecture_Guide (掃文尾二維碼讀原文)


目錄

第1章 概覽

第2章 存儲集群架構

2.1 存儲池

2.2 身份認證

2.3 PG(s)

2.4 CRUSH

2.5 I/O操作

2.5.1 副本I/O

2.5.2 糾刪碼I/O

2.6 自管理的內部操作

2.6.1 心跳

2.6.2 同步

2.6.3 數據再平衡與恢復

2.6.4 校驗(或擦除)

2.7 高可用

2.7.1 數據副本

2.7.2 Mon集群

2.7.3 CephX

第3章 客戶端架構

3.1 本地協議與Librados

3.2 對象的監視與通知

3.3 獨佔鎖

3.4 對象映射索引

3.5 數據條帶化

第4章 加密


第1章 概覽

Red Hat Ceph是一個分散式的數據對象存儲,系統設計旨在性能、可靠性和可擴展性上能夠提供優秀的存儲服務。分散式對象存儲是存儲的未來,因為它們適應非結構化數據,並且客戶端可以同時使用現代及傳統的對象介面進行數據存取。例如:

本地語言綁定介面(C/C++、Java、Python)

RESTful 介面(S3/Swift)

塊設備介面

文件系統介面

Red Hat Ceph所具備的強大功能可以改變您公司(或組織)的IT基礎架構和管理海量數據的能力,特別是對於像RHEL OSP這樣的雲計算平台。

Red Hat Ceph具有非常好的可擴展性——數以千計的客戶端可以訪問PB級到EB級甚至更多的數據。

譯者注: 數據的規模可以用KB、MB、GB、TB、PB、EB、YB等依次表示,比如1TB = 1024GB。

每一個Ceph部署的核心就是Ceph存儲集群。 集群主要是由2類後台守護進程組成:

Ceph OSD守護進程:Ceph OSD為Ceph客戶端存儲數據提供支持。另外,Ceph OSD利用Ceph節點的CPU和內存來執行數據複製、數據再平衡、數據恢復、狀態監視以及狀態上報等功能。

Ceph 監視器:Ceph監視器使用存儲集群的當前狀態維護Ceph存儲集群映射關係的一份主副本。

Ceph客戶端介面與Ceph存儲集群進行數據讀寫上的交互。客戶端要與Ceph存儲集群通信,則需要具備以下條件:

Ceph配置文件,或者集群名稱(通常名稱為ceph)與監視器地址

存儲池名稱

用戶名及密鑰所在路徑

Ceph客戶端維護對象ID和存儲對象的存儲池名稱,但它們既不需要維護對象到OSD的索引,也不需要與一個集中的對象索引進行通信來查找數據對象的位置。

為了能夠存儲並獲取數據,Ceph客戶端首先會訪問一台Ceph mon並得到最新的存儲集群映射關係,然後Ceph客戶端可以通過提供的對象名稱與存儲池名稱,使用集群映射關係和CRUSH演算法(可控的、可擴展的、分散式的副本數據放置演算法)來計算出提供對象所在的PG和主Ceph OSD,最後,Ceph客戶端連接到可執行讀寫操作的主OSD上進而達到數據的存儲與獲取。客戶端和OSD之間沒有中間伺服器,中間件或匯流排。

當一個OSD需要存儲數據時(無論客戶端是Ceph Block設備,Ceph對象網關或其他介面),從客戶端接收數據然後將數據存儲為對象。每一個對象相當於文件系統中存放於如磁碟等存儲設備上的一個文件。

注: 一個對象的ID在整個集群中是唯一的,(全局唯一)而不僅僅是本地文件系統中的唯一。

Ceph OSD將所有數據作為對象存儲在扁平結構的命名空間中(例如,沒有目錄層次結構)。對象在集群範圍內具有唯一的標識、二進位數據、以及由一組名稱/值的鍵值對組成的元數據。而這些語義完全取決於Ceph的客戶端。例如,Ceph塊設備將塊設備鏡像映射到集群中存儲的一系列對象上。

注: 由唯一ID、數據、名稱/值構成鍵值對的元數據組成的對象可以表示結構化和非結構化數據,以及前沿新的數據存儲介面或者原始老舊的數據存儲介面。


第2章 存儲集群架構

為了有效的實現無限可擴展性、高可用性以及服務性能,Ceph存儲集群可以包含大量的Ceph節點。每個節點利用商業硬體以及智能的Ceph守護進程實現彼此之間的通信:

存儲和檢索數據

數據複製

監控並報告集群運行狀況(心跳)

動態的重新分布數據(回填)

確保數據完整性(清理及校驗)

失敗恢復

對於讀寫數據的Ceph客戶端介面來說,Ceph存儲集群看起來就像一個存儲數據的簡單存儲池。然而,存儲集群背後卻是對客戶端介面完全透明的方式並且會執行許多複雜的操作。Ceph客戶端和Ceph OSD都使用CRUSH演算法(可控的、可擴展的、分散式的副本數據放置演算法),後面的章節會詳細講解CRUSH演算法。

2.1 存儲池

Ceph存儲集群通過『存儲池』這一邏輯劃分的概念對數據對象進行存儲。可以為特定類型的數據創建存儲池,比如塊設備、對象網關,亦或僅僅是為了將一組用戶與另一組用戶分開。

從Ceph客戶端來看,存儲集群非常簡單。當有Ceph客戶端想讀寫數據時(例如,會調用I/O上下文),客戶端總是會連接到存儲集群中的一個存儲池上。客戶端指定存儲池名稱、用戶以及密鑰,所以存儲池會充當邏輯劃分的角色,這一角色使得對數據對象訪問進行控制。

實際上,存儲池不只是存儲對象數據的邏輯劃分,它還扮演著Ceph存儲集群是如何分布及存儲數據的角色,當然了,這些複雜的操作對客戶端來說也是透明的。Ceph存儲池定義了:

存儲池類型:在以前的老版本中,一個存儲池只是簡單的維護對象的多個深拷貝。而現在,Ceph能夠維護一個對象的多個副本,或者能夠使用糾刪碼。正因為保證數據持久化的2種方法(副本方式與糾刪碼方式)存在差異,所以Ceph 支持存儲池類型。存儲池類型對於客戶端也是透明的。

PG:在EB規模的存儲集群中,一個Ceph存儲池可能會存儲數百萬或更多的數據對象。因為Ceph必須處理數據持久化(副本或糾刪碼數據塊)、清理校驗、複製、重新再平衡以及數據恢復,因此在每個對象基礎上的管理就會出現擴展性和性能上的瓶頸。Ceph通過散列存儲池到PG的方式來解決這個瓶頸問題。CRUSH則分配每一個對象到指定的PG中,每個PG再到一組OSD中。

CRUSH規則集:Ceph中,高可用、持久化能力以及性能是非常重要的。CRUSH演算法計算用於存儲對象的PG,同時也用於計算出PG的OSD Acting Set

譯者注:acting set即為活躍的osd集合,集合中第一個編號的osd即為主primary OSD。

CRUSH也扮演著其他重要角色:即CRUSH可以識別故障域和性能域(例如,存儲介質類型、nodes, racks, rows等等)。CRUSH使得客戶端可以跨故障域(rooms, racks, rows等等)完成數據的寫入以便當節點出現粒度比較大的問題時(例如,rack出問題)集群仍然可以以降級的狀態提供服務直至集群狀態恢復。CRUSH也可使客戶端能夠將數據寫入特定類型的硬體中(性能域),例如SSD或具有SSD日誌的硬碟驅動器,亦或具有與數據驅動相同驅動的日誌硬碟驅動器。對於存儲池來說,CRUSH規則集決定了故障域以及性能域。

數據持久化方式:在EB規模的存儲集群中,硬體故障因為可預期所以一般並不算異常。當使用數據對象表示較大粒度的存儲介面時(例如塊設備),對於這種大粒度存儲介面來說,對象的丟失(不管是1個還是多個)都可能破壞數據的完整性進而導致數據不可用。因此,數據丟失是不可容忍也是不能接受的。Ceph提供了2種持久化方式:第1種為副本存儲池方式,這種方式將多份相同內容的數據對象通過CRUSH進行故障域的隔離來存儲到不同的節點上(比如將對象分別存儲在硬體相互隔離的不同節點上),這樣即使硬體問題也不會對數據的持久化能力產生什麼大的影響;第2種為糾刪碼存儲池方式,這種方式將對象存儲到K+M 個塊中,其中K表示數據塊,M 表示編碼塊。K+M的和表示總的OSD數量,可以支持最多同時有M 個OSD出現問題,數據也不會丟失。

從客戶端角度來看,Ceph對外呈現顯得優雅而簡單。客戶端只需要讀取或寫入數據到存儲池。但是,存儲池在數據持久化,性能以及高可用方面發揮著重要的作用。

2.2 身份認證

為了識別用戶並防止中間人攻擊,Ceph提供了cephx認證系統來驗證用戶和守護進程。

注: Cephx協議並不處理傳輸中的數據加密(例如SSL/TLS)也不處理靜態數據加密。

Cephx使用共享的密鑰進行認證,這也意味著客戶端和mon都會有客戶端密鑰副本。認證協議也就是雙方都能夠向對方證明他們擁有密鑰的副本,而不會實際泄露密鑰。這種方式提供了相互認證的機制,意味著集群確信用戶擁有密鑰以及用戶確信集群擁有密鑰的副本。


2.3 PG(s)

Ceph將存儲池分片處理成在集群中均勻且偽隨機分布的PG。CRUSH演算法將每個對象分配到一個指定的PG中,並且將每個PG分配到對應的Acting Set集合中—也就是在Ceph客戶端和存儲對象副本的OSD之間創建一個間接層。 如果Ceph客戶端直接就能知道對象存放到具體的哪個OSD中的話,那麼Ceph客戶端和Ceph OSD之間耦合性就太強了。

相反的,CRUSH演算法會動態的將對象分配到PG中,然後再將PG分配到一組Ceph的OSD中。有了這個間接層之後,當新Ceph OSD加入或者Ceph OSD出現問題時,Ceph存儲集群就可以動態的進行數據再平衡。通過在數百到數千個放置組的環境中管理數百萬個對象,Ceph存儲集群可以高效地增長和收縮以及從故障中恢復。

下面的圖描述了CRUSH是如何將對象分配到PG中,以及PG分配到OSD中的。

相對整體集群規模來說,如果存儲池設置的PG較少,那麼在每個PG上Ceph將會存儲大量的數據;如果存儲池設置的PG過大,那麼Ceph OSD將會消耗更多的CPU與內存,不管哪一種情況都不會有較好的處理性能。 所以,為每個存儲池設置適當數量的PG,以及分配給集群中每個OSD的PG數量的上限對Ceph性能至關重要。

譯者注: PG是對象的集合, 在同一個集合里的對象放置規則都一樣(比如同一集合中的對象統一都存儲到osd.1、osd.5、osd.8這幾台機器中);同時,一個對象只能屬於一個PG,而一個PG又對應於所放置的OSD列表;另外就是每個OSD上一般會分布很多個PG。


2.4 CRUSH

Ceph會將CRUSH規則集分配給存儲池。當Ceph客戶端存儲或檢索存儲池中的數據時,Ceph會自動識別CRUSH規則集、以及存儲和檢索數據這一規則中的頂級bucket。當Ceph處理CRUSH規則時,它會識別出包含某個PG的主OSD,這樣就可以使客戶端直接與主OSD進行連接進行數據的讀寫。

為了將PG映射到OSD上,CRUSH 映射關係定義了bucket類型的層級列表(例如在CRUSH映射關係中的types以下部分)。創建bucket層級結構的目的是通過其故障域和(或)性能域(例如驅動器類型、hosts、chassis、racks、pdu、pods、rows、rooms、data centers)來隔離葉子節點。

除了代表OSD的葉子節點之外,層次結構的其餘部分可以是任意的,如果默認類型不符合你的要求,可以根據自己的需要來定義它。 CRUSH支持一個有向無環圖的拓撲結構,它可以用來模擬你的Ceph OSD節點在層級結構中的分布情況。

因此,可以在單個CRUSH映射關係中支持具有多個Root節點的多個層級結構。例如,可以創建SSD的層級結構、使用SSD日誌的硬碟層級結構等等。

譯者注: CRUSH的目的很明確, 就是一個PG如何與OSD建立起對應的關係。


2.5 I/O操作

Ceph客戶端從Ceph mon獲取『集群映射關係Cluster map,然後對存儲池中的對象執行I/O操作。對於Ceph如何將數據存於目標中來說,存儲池的CRUSH規則集和PG數的設置起主要的作用。擁有最新的集群映射關係,客戶端就會知道集群中所有的mon和OSD的信息。但是,客戶端並不知道對象具體的存儲位置(不知道對象具體存在哪個OSD上)。

對於客戶端來說,需要的輸入參數僅僅是對象ID和存儲池名稱。邏輯上也比較簡單:Ceph將數據存儲在指定名稱的存儲池中(例如存儲池名稱為livepool)。當客戶端想要存儲一個對象時(比如對象名叫 「john」、「paul」、"george」、 「ringo」等),客戶端則會以對象名、根據對象名信息計算的hash碼、存儲池中的PG數、以及存儲池名稱這些信息作為輸入參數,然後CRUSH(可控的、可擴展的、分散式的副本數據放置演算法)就會計算出PG的ID(PG_ID)及PG對應的主OSD信息。

譯者注:根據設置的副本數(比如3副本)則計算出的列表如(osd.1、osd.3、osd.8), 這裡的第一個osd.1就是主OSD。

Ceph客戶端經過以下步驟來計算出PG ID信息。

客戶端輸入存儲池ID以及對象ID(例如,存儲池pool=」liverpool」, 對象ID=」john」)。

CRUSH獲取對象ID後對其進行HASH編碼。

CRUSH根據上一步的HASH編碼與PG總數求模後得到PG的ID。(譯者註:例如HASH編碼後為186,而PG總數為128,則求模得58,所以這個對象會存儲在PG_58中;另外這也可以看出PG數對存儲的影響,因為涉及到對象與PG的映射關係,所以輕易不要調整PG數)

CRUSH計算對應PG ID的主OSD。

客戶端根據存儲池名稱得到存儲池ID(例如」liverpool」=4)。

客戶端將PG ID與存儲池ID拼接(例如 4.58)

客戶端直接與Activtin Set集合中的主OSD通信,來執行對象的IO操作(例如,寫入、讀取、刪除等)。

Ceph存儲集群的拓撲和狀態在會話(I/O上下文)期間相對比較穩定。與客戶端在每個讀/寫操作的會話上查詢存儲相比,Ceph客戶端計算對象存儲位置的速度要更快些。CRUSH演算法不但能使客戶端可以計算出對象應當存儲的位置,同時也使得客戶端可以和Acting Set集合中的主OSD直接交互來實現對象的存儲與檢索。 由於EB規模的存儲集群一般會有數千個OSD存儲節點,所以客戶端與Ceph OSD之間的網路交互並不是什麼大的問題。即使集群狀態發生變化,客戶端也可以通過Ceph mon查詢到更新的集群映射關係。


2.5.1 副本I/O

和Ceph客戶端一樣,Ceph OSD也是通過與Ceph mon交互來獲取到最新的集群映射關係。Ceph OSD也使用CRUSH演算法,但是用這個演算法是用來計算對象的副本應該存儲在什麼位置(譯者注: 客戶端用CRUSH是用來找主OSD以及計算出Acting Set列表,而OSD用CRUSH則是主OSD定位對應的副本是誰)。

在典型的寫操作場景下,Ceph客戶端使用CRUSH演算法計算對象所在的PG ID以及Acting Set列表中的主OSD,當客戶端將對象寫到主OSD時,主OSD會查看這個對象應該存儲的副本個數(例如,osd_pool_default_size = n),然後主OSD根據對象ID、存儲池名稱、集群映射關係這些信息再根據CRUSH演算法來計算出Acting Set列表中的從屬OSD(譯者注: 除列表中第一個OSD外,其它的都是從屬OSD)。

主OSD將對象寫入從屬OSD中,當主OSD收到從屬OSD回復的ACK確認並且主OSD自身也完成了寫操作後,主OSD才會給Ceph客戶端回復真正寫入成功的ACK確認。

通過有代表性的Ceph客戶端(主OSD)執行數據複製的能力,Ceph OSD守護進程相對的減輕了Ceph客戶端的這一職責,同時確保了數據高可用以及安全性。

注: 比較典型的就是主OSD和從屬OSD在部署時會將故障域進行隔離(比如不同時配置到一個rack上或一個row上,亦或是同一個node上)。CRUSH計算從屬OSD的ID也會考慮故障域信息。


2.5.2 糾刪碼I/O

糾刪碼實際上是一種前向錯誤糾正編碼,這種編碼會將K個數據塊通過補充N個編碼塊的方式,將原始數據擴展為更長的消息編碼,以便當N個數據塊出現問題時數據依舊不會丟失。隨著時間的推移,開發了不同的糾刪編碼演算法,其中最早和最常用的演算法之一是Reed-Solomon演算法。

可以通過等式 N = K + M 對這一演算法進行理解,等式中 K 表示數據塊的個數,M 代表了編碼塊的個數,而 N 則是在 糾刪編碼 過程中創建的總的塊的個數。值 M 可以簡化為 N – K ,也就是說在計算原始的K個數據塊時 N – K 個冗餘塊也一併需要計算出來。這種方法保證只要N個塊中的K有效就可以訪問所有原始數據。換句話說,即使有 N – K 個塊出現了故障,對外提供服務的數據仍舊是沒有問題的。

例如配置(N=16,K=10)或者糾刪編碼 10/16,10個基本的塊(K)中會有額外補充的6個塊( M = K-N, 如16-10 = 6 ) 。這16個塊(N)可能對應16個OSD。即使有6個OSD出現問題,原始文件也可以從這10個已經驗證的數據塊中重建恢復。這就意味著不會有任何的數據丟失,因此糾刪碼也具備比較高的容錯能力。

和副本存儲池類似,糾刪碼存儲池也是由up set列表中的主OSD來接收所有的寫操作。在副本存儲池中,Ceph對PG中的每個對象在從屬OSD上都會有一份一樣的數據對象;而對於糾刪碼存儲池來說,可能略有不同。每個糾刪碼存儲池都會以 K+M 個塊來存儲每一個對象。

對象(的數據內容)會被切分成 K 個數據塊以及 M個編碼塊。糾刪碼存儲池創建時也需要配置成 K+M 的大小(size)以便每個塊都可以存儲到Activtin Set列表中的每個OSD上。對象的屬性存儲這些塊的等級。主OSD負責數據劃分到 K+M 個塊的糾刪編碼以及將這些編碼信息發送到其它的OSD上。同時主OSD也會維護PG的權威日誌(譯者注: 權威日誌實際是一種進度控制機制,尤其當某些節點出現問題時,可以根據權威日誌進行數據的恢復)。

例如,使用5個OSD (K + M = 5) 創建糾刪碼存儲池,支持其中2個 (M = 2) 塊的數據丟失。

將對象寫入糾刪碼存儲池中的時候(比如對象名叫 NYAN,內容為 ABCDEFGHI )糾刪碼計算函數會將對象的內容按長度平分成3個塊(即,分成K個數據塊),第一個塊內容為 ABC , 第二個塊內容為DEF , 第三個塊內容為 GHI , 如果塊內長度不是 K 的倍數,那麼平分後最後的一塊所剩餘的空位就會進行填充以使其長度為K(比如內容串為ABCDEFGHIJ,則3個數據塊內容依次為ABCD、EFGH、IJ..,最後的IJ長度不夠就會填充);除了將內容按K切分外, 糾刪碼函數也要創建另外2個編碼塊,即第4個塊內容為 XYZ ,第5個塊內容為 GQC 。

這裡的每一個塊內容都對應Action Set列表中的一個OSD。 這些塊有相同的名稱都叫 NYAN , 但塊存在不同的OSD中。除了名稱之外,數據塊創建的對應序號需要存儲在對象的屬性中( shard_t ) 。 包括 ABC 內容的第一個塊存儲在 OSD5 上,而包括 YXY 內容的第4個塊則存儲在 OSD3 上。

譯者注: 注意上圖中,5個塊的名稱都叫NYAN,每個塊的內容為K個均分的內容, 同時被切分後的每個塊都有一個唯一序號shard, 每個塊都對應不同的OSD,即塊按HOST進行故障域隔離。

譯者注: 比如以下配置及圖例中,K=4, M=2 並且以rack作為故障域)

如果從糾刪碼存儲池中讀取對象 NYAN, 解碼函數需要讀取3個塊: 包括ABC 的第一個塊, 包括GHI 的第3個塊以及包括YXY 的第4個塊;然後重構出對象的內容ABCDEFGHI 。解碼函數來通知第2個塊和第5個塊缺失(一般稱為糾刪或擦寫)。

可在這2個缺失的塊中,第5個塊缺失可能因為OSD4 狀態是OUT而讀不到,只要讀到3個塊可讀的話,解碼函數就可以被調用:因為OSD2對應的是最慢的塊,所以讀取時排除掉不在考慮之內。

將數據拆分成不同的塊是獨立於對象放置規則的。CRUSH規則集和糾刪碼存儲池配置決定了塊在OSD上的放置。例如,在配置中如果使用lrc(局部可修復編碼)插件來創建額外塊的話,那麼恢複數據的話則需要更少的OSD。

例如lrc配置信息: K=4、M=2、L=3 中,使用jerasure插件庫來創建6個塊(K+M),但局部值(L=3 )則要求需要再創建2個局部塊。額外創建的局部塊個數可以通過(K+M)/L 來計算得出。如果0號塊的OSD出現問題,那麼這個塊的數據可以通過塊1,塊2以及第一個局部塊進行恢復。在這個例子中,恢復也只需要3個塊而不是5個塊。關於CRUSH、糾刪碼配置、以及插件的內容,可以參考存儲策略指南。

注: 糾刪碼存儲池的對象映射是失效的,不能設置為有效狀態。關於對象映射的更多內容,可以參考對象映射章節。

注: 糾刪碼存儲池目前公支持RADOS網關(RGW),對於RADOS的塊設備(RBD)目前還不支持。


2.6 自管理的內部操作

Ceph集群也會自動的執行一些自身狀態相關的監控與管理工作。例如,Ceph的OSD可以檢查集群的健康狀態並將結果上報給後端的Ceph mon;再比如,通過CRUSH演算法將對象映射到PG上,再將PG映射到具體的OSD上;同時,Ceph OSD也通過CRUSH演算法對OSD的故障等問題進行自動的數據再平衡以及數據恢復。 以下部分我們將介紹Ceph執行的一些操作。


2.6.1 心跳

Ceph OSD加入到集群中並且將其狀態上報到Ceph mon。在底層實現上,Ceph OSD的狀態就是up或為down ,這一狀態反映的就是OSD是否運行並為Ceph客戶端的請求提供服務。如果Ceph OSD在集群中的狀態是donw且為in ,那麼表明此OSD是有問題不能提供服務的;如果Ceph OSD並沒有運行(比如服務crash掉了),那麼這個Ceph OSD也不能上報給Ceph mon其自身狀態為Down 。

Ceph mon會定期的ping 這些OSD以此來確信這些OSD是否仍在運行。當然了,Ceph也提供了更多的機制,比如使Ceph OSD可以評判與之關聯的OSD是否狀態為down(譯者註:比如在副本OSD間相互ping狀態的關係,沒有副本關係的話,OSD之間不會建立連接亦即更不會ping彼此),以及更新Ceph的集群映射關係並上報給Ceph mon。由於OSD分擔了部分工作,所以對於Ceph mon來說,工作內容相對要輕量很多。


2.6.2 同步

Ceph OSD守護進程執行同步,這裡的同步指的是將存儲放置組(PG)的所有OSD中對象狀態(包括元數據信息)達到一致的過程。同步問題通常都會自行解決無需人為的干預。

注: 即使Ceph mon對於OSD存儲PG的狀態達成一致,這也並不意味著PG擁有最新的內容。

當Ceph存儲PG到OSD的acting set列表中的時候,會將它們分別標記為主,從等等。慣例上,Acting set列表中的第一個是主OSD,主OSD也負責協調組內的PG進行同步操作,這裡的主OSD也是唯一 接收客戶端的寫入對象到給定PG請求的OSD。

當一系列的OSD負責一個放置組PG,則這一系列的OSD,我們稱它們為一個Acting Set。Acting Set可能指的是當前負責放置組的Ceph OSD守護進程或者某個有效期內,負責特定放置組的OSD守護進程。

Acting Set中的部分Ceph OSD可能不會一直是up 狀態。當Acting Set中的OSD狀態是up 狀態時,那麼這個OSD也是Up Set中的成員。相對Acting Set來說,Up Set是非常重要的,因為當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 數據再平衡與恢復

當我們向Ceph存儲集群中新增加Ceph OSD的時候,集群映射關係隨著新增加的OSD同時也會更新。因此,由於這一變化改變了計算CRUSH時提供的輸入參數,所以也就間接的改變了對象的放置位置。CRUSH演算法是偽隨機的,但會均勻的放置數據。所以集群中新增加一台OSD時,也只會有一小部分的數據發生遷移。一般遷移的數據量是集群總數據量與OSD數量的比值(例如,在有50個OSD的集群中,當新增加一台OSD時也只有1/50 或者2%的數據受到遷移影響)。

下面的圖示描述了部分的PG(非全部PG)從已有的OSD 1,OSD 2上遷移到新OSD 3上達到數據再平衡的過程(因為對大型集群的影響要小得多,所以過程相對粗略一些)。 即使在再平衡過程中,CRUSH也是穩定的。大部分的PG仍然保留著原始的配置,由於新增加了OSD,所以每個OSD都會增加一些(可用的)容量,因此在重新平衡完成後,新的OSD上也不會出現負載峰值的情況。


2.6.4 校驗(或擦除)

作為Ceph中維護數據一致性以及整潔性的部分,Ceph OSD 守護進程也可以完成PG內的對象清理工作,意思就是Ceph OSD守護進程比較副本間PG內的對象元數據信息。校驗/擦除(通常是天級別的調度策略)捕獲異常或文件系統的一些錯誤。同時,Ceph OSD守護進程也可以進行更深層次的比較(對象數據本身的按位比較),而這種深層次的比較(可以發現驅動盤上壞的扇區)一般是周級別的調度策略。


2.7 高可用

除了通過CRUSH演算法實現高可擴展性外,Ceph也需要支持高可用性。這就意味著即使集群處於降級狀態或某個Ceph mon出現問題情況下(譯者註:這裡出問題的mon個數不能超過mon總數的一半,否則集群會阻塞所有操作),客戶端仍舊可以進行數據的讀寫。


2.7.1 數據副本

在副本存儲池中,Ceph需要對象的多個副本在降級狀態下運行。理想情況下,即使Acting Set中的一個OSD出現問題,Ceph存儲集群也可以支持客戶端讀寫操作。基於此,Ceph默認也是一個對象保持3副本的設置,寫操作則要求至少2個副本為clean狀態(譯者注: 具體設置多少個副本為clena才支持寫操作,這要依賴於設置存儲池時的配置,例如,在ceph osd dump | grep pool輸出中的replicated size 3 min_size 2,這裡的2就是至少有多少個副本為clean,在這個存儲池上的寫操作才被支持,而這個值是可以再更新的)。

如果有2個OSD出現問題,Ceph仍然可以保留數據不會丟失,但是就不能進行寫操作了。

在糾刪碼存儲池中,Ceph需要多個OSD來存儲對象分割後的塊以便在降級狀態仍然可以操作。與副本存儲池類似,理想情況下,在降級狀態下糾刪碼存儲池也支持Ceph客戶端進行讀寫操作。基於此,我們則建議設置K+M=5 通過5個OSD來存儲塊信息,同時設置M=2 以保證即使2個OSD出現問題也可以根據剩餘的OSD進行數據的恢復重建。


2.7.2 Mon集群

在客戶端進行數據讀寫之前,客戶端必須從Ceph mon端獲取最新的集群映射關係。一個Ceph存儲集群可以與一台mon進行通信發起操作,然而這就存在單點問題(例如這個單點的mon出現問題,Ceph客戶端則不能進行數據的讀寫)。

為了提供服務的可靠性以及容錯性,Ceph支持mon組成集群方式提供服務。在mon集群中,延遲和其他的故障可能導致一個或多個mon落後於集群當前的狀態。基於此,Ceph必須在集群狀態的各種mon實例之間達成一致。對於集群當前的狀態,Ceph也總是使用大多數的mon(例如: 1、2:3、3:5、4:6等等)或者Paxos演算法進行一致性確認。同時,mon集群內機器間也需要NTP時間服務防止時鐘漂移。


2.7.3 CephX

Cephx 認證協議的操作方式與Kerberos類似。用戶、角色調用Ceph客戶端來與mon交互,不像Kerberos,每一個monitor都可以對用戶進行認證並分發密鑰,所以使用cephx 不存在單點問題或瓶頸。mon返回類似於Kerberos的包含會話密鑰信息的結構以便調用方可以根據密鑰對接Ceph的所提供的服務。這裡的會話密鑰本身使用了用戶的永久密鑰進行加密,因此只有用戶自已才可以從Ceph mon請求服務。

客戶端使用會話密鑰從monitor處獲取想要的服務,mon則通過認證使得客戶端有許可權對接OSD來完成數據交互。Ceph mon和OSD共享一個秘鑰,因此客戶端可以使用mon提供的憑證與群集中的任何OSD或元數據伺服器進行交互。和Kerberos類似,cephx 憑證也有超時時間,所以並不能使用一個超時的憑證偷偷的對集群進行攻擊。只要用戶的密鑰在到期前不泄露的話,這種身份認證的形式可以防止攻擊者以其他用戶的身份創建偽造消息或更改其他用戶的合法消息訪問通信介質。

如果使用Cephx 認證,管理員必須先設置用戶。在下面的圖示中,client.admin 用戶通過命令行執行ceph auth get-or-create-key 命令,創建用戶以及密鑰。Ceph的auth 子系統生成用戶名以及密鑰,並將其存於mon中以及將用戶名與密鑰返回給調用命令的client.admin 用戶。 這也就意味著客戶端與mon共享同一個密鑰。

注: client.admin 用戶必須以安全的方式向用戶提供用戶ID和密鑰。


第3章 客戶端架構

Ceph客戶端在數據存儲的介面方面還是存在比較大的差異的。Ceph的塊設備提供了可以像掛載本地物理驅動盤一樣的塊存儲,而Ceph對象網關則通過用戶的管理提供了兼容S3與Swift的Restful對象存儲介面。而對於這些介面,都是使用的RADOS(可靠且自動分散式的對象存儲)協議與Ceph存儲集群進行的交互;同時這些介面也都有一些相同的基本前提:

Ceph配置文件,或集群名稱(通常為ceph )與mon地址

存儲池名稱

用戶名以及密鑰的路徑

Ceph客戶傾向於遵循一些類似的模式,例如對象的監視-通知以及條帶化。下面大概介紹下Ceph客戶端里使用的RADOS,librados以及常見的模式。


3.1 本地協議與Librados

現代的應用需要有非同步通信能力簡單的對象存儲介面,Ceph存儲集群就有這個能力並提供簡單的介面。此介面提供了對集群直接、並行的對象存取。

存儲池操作

快照

讀、寫對象

– 創建或刪除

– 整個對象或位元組範圍

– 追加或截斷

創建/設置/獲取/刪除 XATTRs

創建/設置/獲取/刪除 K/V對

複合操作和雙重ack語義


3.2 對象的監視與通知

Ceph客戶端可以為對象註冊持久的關注點,並保持與主OSD的會話開啟。客戶端可以向所有觀察者發送通知消息和數據,並在觀察者收到通知時接收通知。這使得客戶端可以使用任何對象作為同步/通信的通道。


3.3 獨佔鎖

獨佔鎖提供一種功能特性:任一客戶端可以對RBD中資源進行』排它的』鎖定(如果有多個終端對同一RBD資源進行操作時)。這有助於解決當有多個客戶端嘗試寫入同一對象時發生衝突的場景。此功能基於前一節中介紹的對象的監視與通知。因此,在寫入時,如果一個客戶端首先在對象上建立獨佔鎖,那麼其它的客戶端如果想寫入數據的話就需要在寫入前先檢查是否在對象上已經放置了獨佔鎖。

設置了這一特性的話,同一時刻只有一個客戶端能夠對RBD資源進行修改,尤其像快照創建與刪除這種改變RBD內部結構的時候。這一特性對於失敗的客戶端也起到了一些保護的作用,例如,虛擬機沒有響應了,然後在其他地方使用同一塊磁碟啟動它的副本,那麼這個無響應的虛擬機將在Ceph中被列入黑名單,並且無法破壞新的虛擬機中數據。

強制的獨佔鎖功能特性默認是不開啟的,但是可以在創建鏡象時顯示的通過加入–image-features參數來開啟這一特性,例如:

rbd -p mypool create myimage –size 102400 –image-features 5

這裡的5是1與4的和值, 其中1使得分層特性生效,4使得獨佔鎖特性生效。所以執行上面這個命令後會創建100GB的RBD鏡象,同時既支持分層特性也支持獨佔鎖特性。

強制的獨佔鎖也是後面提到的對象索引映射使用的前提。如果沒有開啟強制的獨佔鎖,那麼對象索引映射也不會生效。

獨佔鎖也為mirror這塊內容做了不少的工作。


3.4 對象映射索引

對象映射索引也是一種功能特性,可以在客戶端寫入rbd映像時跟蹤RADOS對象是否已經存在了。當有寫入操作時,寫操作被轉義為RADOS對象中的偏移,如果對象映射索引功能開啟那麼對於存在的RADOS對象就會被跟蹤到。所以當對象已經存在時我們就可以提前知道。對象映射索引保存在librbd客戶端機器內存中,所以對於不存在的對象就省去了再去查詢OSD的這一步開銷。對象映射索引對於一些操作還是比較有利的,即:

調整大小

導出操作

複製操作

扁平化

刪除

讀取

縮小操作就像是對尾部對象的部分刪除。導出操作知道哪些對象被RADOS請求。複製操作知道哪些對象存在並需要複製。它不需要遍歷潛在的數百或數千個可能的對象。扁平化操作將所有父對象拷貝到克隆中,以便可以將克隆與父項分離,即可以刪除從子克隆到父快照的引用。因此,不是對所有潛在的對象,僅是對存在的對象進行複製。

刪除操作僅刪除鏡象中存在的對象。讀取操作對於不存在的對象會直接跳過。因此,對於調整大小(僅縮小)、導出操作、複製操作、扁平化和刪除等操作,這些操作需要針對所有可能受到影響的RADOS對象(無論它們是否存在)發布操作。如果啟用對象映射索引特性的話,對象若不存在就不需要發布操作了。

例如,我們有一個RBD鏡象,有1TB的數據且比較稀疏,可能擁有數百或數千個RADOS對象。如果不開啟對象映射索引的話,執行刪除操作則需要對每一個潛在的目標對象發布刪除對象操作;但是如果開啟了這一特性,那麼只需要對真正存在的對象發布一個刪除對象的操作就可以了。

對象映射索引對於克隆是比較有價值的(自身沒有實際對象但可以從父對象那獲取)。當有一個克隆的鏡象時,克隆初始並沒有什麼對象,所有對克隆對象的讀操作都會重定向到父對象中。開啟對象映射索引可以改善讀操作,首先對於克隆對象向OSD發布讀操作,如果讀失敗了,那麼再向克隆對象的父對象發布讀操作。讀操作會直接忽略掉根本不存在的對象。

對象映射索引默認是不開啟的,但是可以在創建鏡象時顯示的通過加入–image-features參數來開啟這一特性。同時獨佔鎖 也是對象映射索引功能特性的使用前提。如果不開啟獨佔鎖功能特性則對象映射索引也不會生效。創建鏡象時如果開啟對象映射索引,可以執行:

rbd -p mypool create myimage –size 102400 –image-features 13

這裡的13是1、4、8的和值, 其中1 使得分層特性生效,4 使得獨佔鎖特性生效,8 使得對象映射索引特性生效。所以執行上面這個命令後會創建100GB的RBD鏡象,同時既支持分層特性也支持獨佔鎖特性和對象映射索引特性。


3.5 數據條帶化

存儲設備一般在吞吐量上都有限制,這就會影響到服務的性能和伸縮性。因此,存儲系統一般會提供條帶化方案來提高性能與吞吐能力(即,將有序的信息分割成多個區段後存儲到多個設備上)。關於條帶化最常見的就是RAID(譯者注: 磁碟陣列RAID,意為將多個磁碟組合成一個容量更大的磁碟組,利用單塊盤存儲的疊加效果來提升整個磁碟存儲冗餘能力。採用這種方案後,將存儲的數據切割成許多個區段數據,然後分別存放在各個硬碟上)。與Ceph中條帶化最相似的RAID類型就是RAID 0或』條帶化卷』。Ceph的條帶化提供了RAID 0級的吞吐能力以及n路RAID鏡像的可靠性和快速的數據恢復能力。

Ceph提供3種客戶端對接類型: Ceph塊設備(CephRBD)、Ceph文件系統(CephFS)、Ceph對象存儲(一般是Ceph RGW)。數據存儲方面,Ceph客戶端會將用戶提交的數據轉換為Ceph存儲集群內部的格式存儲到集群中,在提供給用戶的介面上也是按照這3種類型完成的:塊設備鏡像、對象存儲的RESTful介面、以及CephFS系統目錄。

提示: 存儲在Ceph存儲集群中的對象自身並沒有條帶化。 Ceph對象存儲,Ceph塊設備和Ceph文件系統將客戶端數據條帶化後存儲在Ceph集群內的多個對象中。如果想充分發揮並行能力,使用librados庫直接將數據寫入到Ceph存儲集群的Ceph客戶端必須執行條帶化(以及並行I/O)。

最簡單的Ceph條帶化格式即為條帶數量為1的單個對象。 Ceph客戶端將條帶單元塊寫入到Ceph存儲集群對象中,直到對象達到其最大容量,然後再為額外的條帶化數據創建另一個對象。對於較小的塊設備鏡像、S3或Swift對象來說,這種簡單的條帶化方式可能就完全能夠滿足需求,然而,這種簡單的形式並沒有最大限度的利用Ceph在整個放置組中分布數據的能力,因此並不能有較大的性能提升。下面圖示描述了這種最簡單的條帶化方式:

譯者注: 例如每一個對象存儲上限是4M,同時每一個單元塊佔1M,這時我們有一個8M大小的文件想進行存儲,這樣前4M存儲在對象0中,後4M就創建另一個對象1來存儲。

如果可以預知存儲需求為較大的圖像,或較大的S3對象或Swift對象(例如視頻),若想有較大的讀寫性能提升,則可以通過將客戶端數據條帶化分割存儲到多個對象上。如果客戶端將條帶單元塊並行的寫入到對應對象中,由於對象映射到不同的PG上進而會映射到不同的OSD上,每個寫操作都以最大化速並行進行,那麼寫性能的提升是相當明顯的。

如果完全只對一塊磁碟寫入操作的話,受限就比較多: 磁頭的移動(例如每次6ms的定址時間開銷)、設備的帶寬(例如每秒最大100MB)。通過擴展多個對象上的寫入(映射到不同的PG以及OSD上),Ceph不但可以降低每個驅動盤的定址時間,同時也可以合併多個驅動盤的吞吐能力以獲取更快的讀寫速度。

注: 條帶化獨立於對象的副本。由於CRUSH跨OSD複製對象,所以條帶化也會自動完成複製。

在下面的圖示中,客戶端跨越對象集(對象集 1)來獲取條帶數據。對象集中由4個對象組成,第1個條帶單元塊是存儲在object 0中的stripe unit 0,第4個條帶單元塊是存儲在 object 3中的stripe unit 3。當寫完第4個單無塊時,客戶端會判斷對象集是否已滿,如果沒有滿的話,客戶端繼續將條帶單元塊寫入第1個對象中(下圖中的object 0)。如果對象集已滿,那麼客戶端就會創建一個新的對象集(下圖中的對像集 2),然後將第1個條帶單元塊(stripe unit 16)寫入到新對象集中的第1個對象中(下圖中的object 4)。

Ceph數據條帶化過程中,有3個比較重要的參數會對條帶化產生影響:

對象大小:Ceph存儲集群中可以配置對象大小的上限值(比如2M、4M等),對象大小也應該足夠的大以便與條帶單元塊相適應,同時設置對象的大小也應該是單元塊大小的倍數。Red Hat則建議對象大小比較合理的值是16MB。

條帶寬度:條帶化中的單元塊大小也是可配置的(例如64kb)。Ceph客戶端將寫入對象的數據劃分為相同大小的條帶單元塊(因為寫入的數據不一定是單元塊的倍數,所以最後剩餘的一個單元塊可能大小與其它的不一樣)。條帶寬度應該是對象大小的一個分數(比如對象是4M,單元塊是1M,則一個對象能包含4個單元塊),以便對象可以包含更多條帶單元塊。(譯者註:條帶寬度也是指同時可以並發讀或寫的條帶數量。一般這個數量等於RAID中的物理硬碟數量)

條帶數量:根據條帶數量,Ceph客戶端將一批條帶單元塊寫入到一系列對象中。這裡的一系列對象也就是對象集。在Ceph客戶端寫入對象集中最後一個對象之後會返回到對象集中的第1個對象。

重要提示: 在服務上線生產環境前,最好對條帶化進行性能上的測試,因為一旦數據寫入,就無法再更改條帶參數信息了。

一旦Ceph客戶端將條帶化數據映射到條帶單元塊上,進而映射到對象上,在對象最終以文件形式存儲在磁碟上之前,Ceph的CRUSH演算法會將對象映射到PG中,然後再將PG映射到OSD守護進程中。

注: 由於客戶端寫入單個存儲池中,因此條帶化到對象中的所有數據都會映射到同一個存儲池的PG內。所以也會使用相同的CRUSH映射關係以及相同的訪問控制策略。

譯者注: 在Ceph存儲中,涉及條帶化的主要是Order、stripe_unit和stripe_count這3個參數。由這3個參數確定了數據的寫入與存儲編排方式。默認情況order是22,也即對象大小為4MB(2的22次方),strip_unit大小與對象大小一致(也是4M),strip_count為1(對象集中只有1個對象)。


第4章 加密相關

LUKS磁碟加密及帶來的好處:在Linux系統中,可以使用LUKS方法對磁碟分區進行加密,由於LUKS是對整個塊設備進行加密,所以對於攜帶型存儲能夠起到較好的數據保護作用。

可以使用Ceph-ansible工具創建加密的OSD存儲節點,這樣可以對OSD上存儲的數據進行保護。更詳細的內容可以參考中的Ceph OSD配置章節。

如何使用ceph-ansible創建加密的磁碟分區:在OSD安裝過程中,ceph-ansible會調用ceph-disk工具來完成創建加密分區的工作。

除了數據和日誌分區外(Ceph data和ceph journal),ceph-disk 工具也會創建一個小的密碼箱分區以及名稱為cephx client.osd-lockbox 的用戶。ceph密碼箱分區包含一個密鑰文件,client.osd-lockbox 用戶使用這個密鑰文件獲取LUKS私鑰,從而對ceph data和ceph journal分區進行解密。

之後,Ceph-disk會再調用cryptsetup 工具為ceph data和ceph journal分區創建2個dm-crypt設備。其中dm-crypt設備使用ceph data和ceph journal的GUID作為標識。

Ceph-ansible如何處理LUKS密鑰: Ceph-ansible工具將LUKS私鑰存儲在Ceph monitor監視器的K/V存儲中。每個OSD都有自己的密鑰將存儲在dm-crypt設備上加密的OSD數據和日誌進行解密。加密分區在服務啟動時就自動的進行了解密操作。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 架構師技術聯盟 的精彩文章:

圖說分散式架構的發展和演進
淺析PureStorage業界首款AI存儲系統AIRI

TAG:架構師技術聯盟 |