CRUSH詳解

CRUSH詳解

CRUSH簡介

CRUSH全稱Controlled Replication Under Scalable Hashing,是一種數據分發算法,類似於哈希和一致性哈希。哈希的問題在於數據增長時不能動態加Bucket,一致性哈希的問題在於加Bucket時數據遷移量比較大,其他數據分發算法依賴中心的Metadata服務器來存儲元數據效率較低,CRUSH則是通過計算、接受多維參數的來解決動態數據分發的場景。
算法基礎

在學習CRUSH之前,需要了解以下的內容。
CRUSH算法接受的參數包括cluster map,也就是硬盤分佈的邏輯位置,例如這有多少個機房、多少個機櫃、硬盤是如何分佈的等等。cluster map是類似樹的多層結果,子節點是真正存儲數據的device,每個device都有id和權重,中間節點是bucket,bucket有多種類型用於不同的查詢算法,例如一個機櫃一個機架一個機房就是bucket。
另一個參數是placement rules,它指定了一份數據有多少備份,數據的分佈有什麼限制條件,例如同一份數據不能放在同一個機櫃裏等的功能。每個rule就是一系列操作,take操作就是就是選一個bucket,select操作就是選擇n個類型是t的項,emit操作就是提交最後的返回結果。select要考慮的東西主要包括是否衝突、是否有失敗和負載問題。
算法的還有一個輸入是整數x,輸出則是一個包含n個目標的列表R,例如三備份的話輸出可能是[1, 3, 5]。
這裏寫圖片描述

圖雖然很複雜,但如果理解了幾個基本操作的含義就很好讀下來了,這裏是三個操作的僞代碼,take和emit很好理解,select主要是遍歷當前bucket,如果出現重複、失敗或者超載就跳過,其中稍微複雜的“first n”部分是一旦遇到失敗,第一種情況是直接使用多備份,第二種情況是使用erasing code基本可以忽略。看着下面的圖就更好理解具體的算法了。
這裏寫圖片描述

MAP改變和數據遷移

當添加移除存儲設備,或有存儲設備發生故障時(cluster map發生改變時),存儲系統中的數據會發生遷移。好的數據分佈算法可以最小化數據遷移大小

Bucket的類型

CRUSH映射算法解決了效率和擴展性這兩個矛盾的目標。而且當存儲集羣發生變化時,可以最小化數據遷移,並重新恢復平衡分佈。CRUSH定義了四種具有不同算法的的buckets。每種bucket基於不同的數據結構,並有不同的c(r,x)僞隨機選擇函數。

不同的bucket有不同的性能和特性:

  • Uniform Buckets:適用於具有相同權重的item,而且bucket很少添加刪除item。它的查找速度是最快的。
  • List Buckets:它的結構是鏈表結構,所包含的item可以具有任意的權重。CRUSH從表頭開始查找副本的位置,它先得到表頭item的權重Wh、剩餘鏈表中所有item的權重之和Ws,然後根據hash(x, r, item)得到一個[0~1]的值v,假如這個值v在[0~Wh/Ws)之中,則副本在表頭item中,並返回表頭item的id。否者繼續遍歷剩餘的鏈表。
  • Tree Buckets:鏈表的查找複雜度是O(n),決策樹的查找複雜度是O(log n)。item是決策樹的葉子節點,決策樹中的其他節點知道它左右子樹的權重,節點的權重等於左右子樹的權重之和。CRUSH從root節點開始查找副本的位置,它先得到節點的左子樹的權重Wl,得到節點的權重Wn,然後根據hash(x, r, node_id)得到一個[0~1]的值v,假如這個值v在[0~Wl/Wn)中,則副本在左子樹中,否者在右子樹中。繼續遍歷節點,直到到達葉子節點。Tree Bucket的關鍵是當添加刪除葉子節點時,決策樹中的其他節點的node_id不變。決策樹中節點的node_id的標識是根據對二叉樹的中序遍歷來決定的(node_id不等於item的id,也不等於節點的權重)。
  • Straw Buckets:這種類型讓bucket所包含的所有item公平的競爭(不像list和tree一樣需要遍歷)。這種算法就像抽籤一樣,所有的item都有機會被抽中(只有最長的籤才能被抽中)。每個籤的長度是由length = f(Wi)hash(x, r, i) 決定的,f(Wi)和item的權重有關,i是item的id號。c(r, x) = MAXi(f(Wi) hash(x, r, i))。

這裏寫圖片描述
不同Bucket的算法複雜度和數據遷移大小
要根據存儲系統中設備的情況和預期擴展計劃來選擇不同的bucket。

算法流程

假設我組建一套存儲系統,有3個機架(host),每個機架上有4臺主機(host),每個主機上有2個磁盤(device),則一共有24個磁盤。預計的擴展方式是添加主機或者添加機架。
這裏寫圖片描述
我們的bucket有三種: root、rack、host。root包含的item是rack,root的結構是straw。rack包含的item是host,rack的結構是tree。host包括的item是device,host的結構式uniform。這是因爲每個host包括的device的數量和權重是一定的,不會改變,因此要爲host選擇uniform結構,這樣計算速度最快。

參考

[1]Ceph From Scratch CRUSH詳解
https://tobegit3hub1.gitbooks.io/ceph_from_scratch/content/architecture/crush.html
[2]ceph的CRUSH數據分佈算法介紹
http://way4ever.com/?p=122
[3]ceph的CRUSH算法的源碼分析
http://way4ever.com/?p=123

發佈了118 篇原創文章 · 獲贊 16 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章