1. 程式人生 > >Ceph學習筆記(2)- CRUSH資料分佈演算法

Ceph學習筆記(2)- CRUSH資料分佈演算法

## 前言: ​ 分散式儲存系統需要讓資料均勻的分佈在叢集中的物理裝置上,同時在新裝置加入,舊裝置退出之後讓資料重新達到平衡狀態尤為重要。新裝置加入後,資料要從不同的老裝置中遷移過來。老裝置退出後,資料遷移分攤到其他裝置。將檔案、塊裝置等資料分片,經過雜湊,然後寫入不同的裝置,從而儘可能提高I/O併發與聚合頻寬。 ​ 在實際場景中如何通過最小資料遷移使得叢集恢復平衡,如何分配備份到裝置上,使得資料儘可能的安全是很重要的問題。Ceph對普通雜湊函式擴充套件後解決了上述問題,Ceph基於雜湊的資料分佈演算法就是CRUSH。 ​ CRUSH支援副本、Raid、糾刪碼資料備份策略,並受控的將資料的多個備份對映到叢集不同故障域的底層裝置上。 ### straw演算法 最初提供了四種基本選擇演算法: ![](https://img2020.cnblogs.com/blog/1480358/202004/1480358-20200402155032231-1255488994.png) ​ 觀察圖中資料得到,unique執行效率最高,抵禦結構變化能力最差,straw演算法執行效率相較unique於tree要差,但是抵禦結構變化的能力最強。因為資料可靠性最為重要,隨著擴容引入越來越多的裝置加上使用時間的推移,叢集裝置需要經常更換韌體,因此目前基本生產環境的Ceph叢集都選擇straw演算法。 ​ straw演算法為每個元素隨機計算一個籤長,選擇籤長最長的元素輸出,籤長越長的元素被選中的概率越大,資料落在上面的概率就越大。straw演算法通過累計當前元素與前後元素的權重差值作為計算下一個元素籤長的基準,因此在每次加入或刪除osd時,都會引起不相干的資料遷移。後修改為籤長計算僅與自身權重有關係,避免了這一現象,稱為straw2演算法,此演算法目前為ceph的預設演算法。 ## cluster map ​ cluster map是叢集層級拓撲結構的邏輯描述形式,其簡單的拓撲如:資料中心->機加->主機->磁碟,因此cluster map採用樹這種資料結構。根節點root是整個叢集的入口;所有葉子節點device都是真實的最小物理儲存裝置(磁碟);中間節點bucket可以是device的集合,也可以是低階的bucket的集合。 ​ cluster map這種層級關係通過這樣一張二維表對映,每個bucket,都儲存自身所有直接孩子的編號,即items。當items為空時,表明bucket為葉子節點。 簡單圖示如下,最下面的葉子節點device(如磁碟)存放資料,中間是host型別的bucket(物理主機),最上面root是叢集入口: ![](https://img2020.cnblogs.com/blog/1480358/202004/1480358-20200402155123404-1086945125.png) 配置示例: ```bash host default_10.10.10.125 { # 型別host,名字為default_10.10.10.125 id -3 # bucket的id,root與bucket的數字標識都為負值,只有device是 非負的數字標識,表明device是承載資料的真實裝置。 # weight 14.126 # 權重,預設為子item的權重之和 alg straw2 # bucket的隨機選擇演算法,這裡用 straw2 hash 0 # rjenkins1 # 使用hash函式rjenkins1 item osd.0 weight 6.852 # osd.0的權重 item osd.1 weight 7.274 # osd.1的權重 } ``` ## placement rule ​ cluster map定義了儲存叢集的物理拓撲描述。placement rule完成資料對映,即決定一個PG的物件副本如何選擇的規則,使用者可自定義副本在叢集中的分佈。 placement rule可含有多個操作,包括以下三種類型: 1. take:從cluster map中選擇指定編號的bucket,系統預設為root型別的節點 2. select:接收take輸入的bucket,從中隨機選擇指定型別和數量的item。 `step [choose|chooseleaf] [firstn|indep] type ` [choose|chooseleaf]:choose操作有不同的選擇方式 * choose選擇出Num個型別為bucket-type的子bucket * chooseleaf選擇出Num個型別為bucket-type的子bucket,然後遞迴到葉子節點選擇一個OSD裝置 [firstn|indep]:ceph有兩種select演算法(均為深度優先遍歷)。不同之處在於糾刪碼要求的結果是有序的,因此如果指定輸出數量為4而無法滿足時: * firstn(多副本):[1,2,4] * indep(糾刪碼):[1,2,CRUSH_ITEM_NONE,4] [Num] : * Num == 0,選出的子buket為pool設定的副本數 * pool副本數 > Num > 0,選出的子buket為Num * Num < 0, 選出的子buket為pool設定的副本數減去Num的絕對值 [type] :故障域的型別,如果為rack,保證選出的副本都位於不同機架的主機磁碟上,如果為host,則保證 選出的副本位於不同主機上。 如果選中條目因故障、衝突等原因無法使用,則會重新執行select。 3. emit:輸出選擇結果 配置示例: ```bash rule { id [a unique whole numeric ID] type [ replicated | erasure ] min_size max_size step take [class ] step [choose|chooseleaf] [firstn|indep] type step emit } ``` ```bash rule data { ruleset 0 //ruleset 編號 type replicated //多副本型別 min_size 1 //副本最小值為1 max_size 10 //副本最大值為10 step take default //選擇default buket輸入{take(default)} step chooseleaf firstn 0 type host //選擇當前副本數個主機下的OSD{select(replicas, type)} step emit //輸出將要分佈的bucket的列表{emit(void)} } ``` ## 選擇方式 CHRUSH演算法依賴以上的演算法(預設為straw2)實現對PG的對映,輸入pg_id、Cluster map、Cluster rule,與隨機因子經過雜湊計算,輸出一組OSD列表,即該pg要落在OSD的編號。 但是選出的OSD有可能會出現衝突或過載,就需要重新選擇: 1. 衝突:指選中條目已經存在於輸出條目中,如osd.1已經存在於輸出列表中,下一個經計算同樣選出了osd.1,此時需要調整隨機因子,再次計算進行選擇。 2. 過載或失效:指選出的OSD無法提供足夠的空間來儲存資料,雖然CRUSH演算法理論上可以讓資料在所有device(磁碟)中均勻分佈,但實際並非如此: * 小規模叢集,PG數量較少,則CRUSH輸入的樣本容量不夠,導致資料計算分佈不均勻。 * crush自身對於多副本模式資料均勻分佈做的不夠完善。 ceph引入過載測試reweight可人工干預對OSD的選擇概率,reweight的值設定的越高,則通過測試概率越高,因此可以通過降低過載OSD的reweight和增加低負載OSD的reweight來使得資料均衡。 > 引入過載測試也可以區分OSD暫時失效和被永久刪除 > > 如果OSD暫時失效(如拔出對應磁碟一段時間,ceph將其設定為OUT),可以將其reweight的值設定為0.000,利用過載測試將其從候選條目中篩掉,進而將其承載的資料遷移到其他OSD。恢復後再將reweight設定為1.000,即可遷回資料(指OSD離線期間產生的新資料) > > 如果是被永久刪除,那麼它會被從候選條目刪除,即便後續再次新增進來,因為cluster map中的唯一編號變化而承載與之前不同的資料,使得叢集出現大規模的資料均衡。 **學習自:** *《Ceph原始碼分析》 常濤* *《Ceph之RADOS設計原理與實現》 謝型果 嚴軍* *https://docs.ceph.com/docs/kraken/rados/operations/cru