玩轉 Ceph 的正確姿勢

2021-09-07 09:01:06 字數 4659 閱讀 1617

玩轉 ceph 的正確姿勢

本文先介紹 ceph, 然後會聊到一些正確使用 ceph 的姿勢;在集群規模小的時候,ceph 怎麼玩都沒問題;但集群大了(到pb級別),這些準則可是保證集群健康執行的不二法門;

ceph 最初的目標是做乙個分布式檔案系統,直到現在這個目標也不能算完美實現;目前官網上對它的檔案系統還是謹慎推薦的態度(不建議對線上核心業務部署);

業界使用 ceph ,大多是用它的物件儲存;

ceph 支援三種儲存介面:物件儲存 rgw(rados gateway)、塊儲存 rbd(rados block device) 和檔案儲存 cephfs;

這三個介面只是在客戶端的封裝庫不同,到服務端了都是物件儲存;

ceph 物件儲存服務提供了 rest 風格的 api ,它有與 amazon s3 和 openstack swift 相容的介面。也就是通常意義的鍵值儲存,其介面就是簡單的get、put、del和其他擴充套件;

rbd 是通過librbd庫對應用提供塊儲存,主要面向雲平台的虛擬機器提供虛擬磁碟;rbd類似傳統的san儲存,提供資料塊級別的訪問;

目前 rbd 提供了兩個介面,一種是直接在使用者態實現, 通過 qemu driver 供 kvm 虛擬機器使用。 另一種是在作業系統核心態實現了乙個核心模組。通過該模組可以把塊裝置對映給物理主機,由物理主機直接訪問。

ceph 檔案系統服務提供了相容 posix 的檔案系統,可以直接掛載為使用者空間檔案系統。它跟傳統的檔案系統如ext4是乙個型別,區別在於分布式儲存提供了並行化的能力;

除了以上3種儲存介面, 還可以直接使用 librados 的原生介面,直接和rados通訊;

原生介面的優點是是它直接和和應用**整合,操作檔案很方便;但它的問題是它不會主動為上傳的資料分片;乙個1g的大物件上傳,落到 ceph 的儲存磁碟上就是1g的檔案;

而以上三個介面是具有分片功能(即:條帶化 file-striping)

ps:兩個物件的區分

需要說明下,這裡提到兩個物件的概念:乙個是 rgw中的物件儲存,乙個是 ceph 的後端儲存的物件;這兩個需要區分:

eg:使用rgw介面,存放乙個1g的檔案,在使用者介面看到的就是存放了乙個物件(1);而通過rgw 分片成多個物件(2)後最終儲存到磁碟上;

服務端 rados 集群主要由兩種節點組成:一種是為數眾多的、負責完成資料儲存和維護功能的osd(object storage device),另一種則是若干個負責完成系統狀態檢測和維護的monitor。

monitor 集群提供了整個儲存系統的節點資訊等全域性的配置資訊,通過 paxos 演算法保持資料的一致性。

pool是儲存物件的邏輯分割槽,它規定了資料冗餘的型別和對應的副本分布策略;支援兩種型別:副本(replicated)和 糾刪碼( erasure code);目前我們公司內部使用的pool都是副本型別(3副本);

pg( placement group)是乙個放置策略組,它是物件的集合,該集合裡的所有物件都具有相同的放置策略;簡單點說就是相同pg內的物件都會放到相同的硬碟上; pg是 ceph的核心概念, 服務端資料均衡和恢復的最小粒度就是pg;

osd是負責物理儲存的程序,一般配置成和磁碟一一對應,一塊磁碟啟動乙個osd程序;

下面這張圖形象的描繪了它們之間的關係:

講究的pg

乙個pool裡設定的pg數量是預先設定的,pg的數量不是隨意設定,需要根據osd的個數及副本策略來確定:

total pgs = ((total_number_of_osd * 100) / max_replication_count) / pool_count
線上盡量不要更改pg的數量,pg的數量的變更將導致整個集群動起來(各個osd之間copy資料),大量資料均衡期間讀寫效能下降嚴重;

良好的工程實踐建議(掉坑後的教訓)

預先規劃pool的規模,設定pg數量;一旦設定之後就不再變更;後續需要擴容就以 pool 為維度為擴容,通過新增pool來實現(pool通過 crushmap實現故障域隔離);

查詢物件在集群中的儲存的位置,具體分為兩步:

第一步,物件到pg的對映;將物件的id 通過hash對映,然後用pg總數對hash值取模得到pg id:

pg_ id = hash( object_ id ) % pg_num
第二步,pg到osd列表對映; 通過crush演算法計算pg 上的物件分布到哪些osd硬碟上;

crush(pg_id) =⇒ osd
crush演算法是 ceph的精華所在;

crush的目標

先看看crush演算法的希望達成的目標:

資料均勻的分布到集群中;

需要考慮各個osd權重的不同(根據讀寫效能的差異,磁碟的容量的大小差異等設定不同的權重)

當有osd損壞需要資料遷移時,資料的遷移量盡可能的少;

crush演算法

簡單說下crush演算法的過程:

第一步輸入pg id、可供選擇的osd id 列表,和乙個常量,通過乙個偽隨機演算法,得到乙個隨機數,偽隨機演算法保證了同乙個key總是得到相同的隨機數,從而保證每次計算的儲存位置不會改變;

crush_hash( pg_id, osd_id, r ) = draw
第二步將上面得到的隨機數和每個osd的權重相乘,然後挑出乘積最大的那個osd;

( draw &0xffff ) * osd_weight = osd_straw
在樣本容量足夠大之後,這個隨機數對挑中的結果不再有影響,起決定性影響的是osd的權重,也就是說,osd的權重越大,被挑中的概率越大。

到這裡了我們再看看crush演算法如何達成的目標:

通過隨機演算法讓資料均衡分布,乘以權重讓挑選的結果考慮了權重;而如果出現故障osd,只需要恢復這個osd上的資料,不在這個節點上的資料不需移動;

crush優缺點

聊到這裡,crush演算法的優缺點就明顯了:

優點如下:

缺點呢:

看清楚了定址的過程,就明白為啥pg不能輕易變更了;pg是定址第一步中的取模引數,變更pg會導致物件的pg id 都發生變化,從而導致整個集群的資料遷移;

這裡只是做個引子,關於crush演算法,這篇文章講的通俗直白,有興趣的移步:大話ceph--crush那點事兒

ceph 是sega本人的博士**作品, 其博士**被整理成三篇短**,其中一篇就是 crush,

crush**標題為《crush: controlled, scalable, decentralized placement of replicated data》,介紹了crush的設計與實現細節。

(ps:另外兩篇是 rados和 cephfs, 分別講 ceph 的伺服器實現和 ceph 檔案系統的細節實現)

剛開始接觸 ceph,通常會忽略 crushmap,因為即使對它不做任何設定,也不影響我們的正常使用;

一旦集群大了,沒有它集群就處於乙個危險的執行狀態中;

沒有故障域的劃分,整個集群就處於乙個未隔離的資源池中;

乙個物件存過去,可能落在 500個osd硬碟的任意三個上;

如果一塊硬碟壞了,可能帶來的是全域性影響(副本copy,這個硬碟上丟失的pg副本可能分布在全域性各個硬碟上);

使用crushmap 將整個集群的osd 劃分為乙個個故障域,類似將乙個集群按業務劃分成為了多個小集群;每個pool 只會用到特定的 osd,這樣,一旦某個osd 損壞,影響的只是某個業務的某個pool,將故障的範圍控制在乙個很小的範圍內。

良好的工程實踐建議

使用crushmap 劃分故障域,將pool限制在特定的osd list上,osd的損壞只會引起這個pool內的資料均衡,不會造成全域性影響;

物件是資料儲存的基本單元, 一般預設 4mb 大小(這裡指的是rados的底層儲存的物件,非rgw介面的物件)。

物件的組成分為3部分:key 、value、元資料;

對於大檔案的儲存,ceph 提供的客戶端介面會對大檔案分片(條帶化)後儲存到服務端;這個條帶化操作是在客戶端介面程式完成的,在 ceph 儲存集群內儲存的那些物件是沒條帶化的。客戶端通過 librados 直接寫入 ceph 儲存的資料不會分片。

良好的工程實踐建議

對於物件儲存,只使用 ceph 提供的 rgw 介面, 不使用 librados原生介面;不僅有分片功能,擴充套件也更容易(rgw是無狀態的,可水平擴充套件);大量大物件直接存放到 ceph中會影響 ceph 穩定性(儲存容量達到60%後);

上線 ceph 前,先規劃未來一年的預期使用量,為每個 pool 一次性設定 pg之後不再變更; 使用crushmap 設定故障域隔離,將磁碟故障後帶來的資料平衡控制在乙個小的範圍之內。介面方面推薦只使用ceph 提供的rgw 介面,不使用 librados原生介面。做好這些, 你的 ceph 用起來會省心很多。

ceph官網

ceph 中文文件

《ceph原始碼剖析》

RESTful的正確姿勢

很多人都有這樣的疑問 rest 英文 representational state transfer,簡稱rest 描述了乙個架構樣式的網路系統,比如 web 應用程式。它首次出現在 2000 年 roy fielding 的博士 中,roy fielding是 http 規範的主要編寫者之一。在目...

正確姿勢的verticle align

1.先看後面一句 在表單元格中,這個屬性會設定單元格框中的單元格內容的對齊方式。這很容易理解,如果給乙個 的td加乙個vertical align middle的樣式,裡面的內容會垂直居中,同樣的如果給乙個vertical align bottom就會底部對齊,如果給乙個vertical align...

正確上網的姿勢

1.購買國外伺服器,目前使用的是vultr,乙個月5刀。支援支付寶充值,最低10美元起。vultr相關鏈結 2.使用xshell連線伺服器 官方鏈結。安裝完成後新建會話 alt n 依次填寫圖中資訊。名稱可以是vultr或者其他,協議選擇ssh,主機填寫之前的ip address,埠號選擇22。連線...