1. 程式人生 > >一致性hash與CRUSH算法總結

一致性hash與CRUSH算法總結

ldo 影響 tails 哈希函數 sch hash函數 結點 理解 數據

相同之處:都解決了數據緩存系統中數據如何存儲與路由

不同之處:區別在於虛擬節點和物理節點的映射辦法不同

由於一般的哈希函數返回一個int(32bit)型的hashCode。因此,可以將該哈希函數能夠返回的hashCode表示成一個範圍為0---(2^32)-1 環

數據和節點使用相同的hash函數來保證 把數據和節點映射到相同的hash空間上。這樣,按照順時針方向,數據存放在它所在的順時針方向上的那個機器上。這就是一致性哈希算法分配數據的方式!

物理節點: 使用ip或者唯一機器標識為key 映射到環上,hash算法CRC32, MD5,SHA-1等加密算法或者更高效的  MurMurHash非加密算法。

虛擬節點: 使用ip+"#"+num(“192.168.0.1#1”),不同的虛擬節點(i不同)有不同的hash值,但都對應同一個實際機器node

數據: 使用對象名(全路徑名)稱為key,算法同樣是MD5

均衡性:引入虛擬節點(相當於ceph中的pg)方法來保證, 副本的個數*實際節點數,副本必須保持在不同的物理節點

虛擬節點”( virtual node )是實際節點(機器)在 hash 空間的復制品( replica ),一實際個節點(機器)對應了若幹個“虛擬節點”,這個對應個數也成為“復制個數”,“虛擬節點”在 hash 空間中以hash值排列。

“虛擬節點”的hash計算可以采用對應節點的IP地址加數字後綴的方式。例如假設NODE1的IP地址為192.168.1.100。引入“虛擬節點”前,計算 cache A 的 hash 值: Hash(“192.168.1.100”); 引入“虛擬節點”後,計算“虛擬節”點NODE1-1和NODE1-2的hash值: Hash(“192.168.1.100#1”); // NODE1-1 Hash(“192.168.1.100#2”); // NODE1-2

單調性:映入hash環的方法來保證。

一致性哈希采用的做法如下:引入一個環的概念,如上面的第一個圖。先將機器映射到這個環上,再將數據也通過相同的哈希函數映射到這個環上,數據存儲在它順時針走向的那臺機器上。以環為中介,實現了數據與機器數目之間的解藕。這樣,當機器的數目變化時,只會影響到增加或刪除的那臺機器所在的環的鄰接機器的數據存儲,而其他機器上的數據不受影響。

ceph中pg值設置參考: 2的次方。

《learning ceph》這本書裏的計算公式也差不多:

Total PGs = ((Total_number_of_OSD * 100) / max_replication_count) / pool_count

結算的結果往上取靠近2的N次方的值。比如總共OSD數量是160,復制份數3,pool數量也是3,那麽按上述公式計算出的結果是1777.7。取跟它接近的2的N次方是2048,那麽每個pool分配的PG數量就是2048。

一致性hash算法中虛擬節點的設置:

當前節點個數*副本數

數據的路由過程/算法: ceph 中叫CRUSH

object-->virtual node-->machine

對於一個實際機器節點 node, 對應 numberOfReplicas 個虛擬節點,
不同的虛擬節點(i不同)有不同的hash值,但都對應同一個實際機器node,
虛擬node一般是均衡分布在環上的,數據存儲在順時針方向的虛擬node上,
獲得一個最近的順時針節點,根據給定的key 取Hash,
然後再取得順時針方向上最近的一個虛擬節點對應的實際節點,
 查看MD5算法生成的hashCode值---表示整個哈希環中各個虛擬節點位置

代碼參考: 下面第一個鏈接。

一致性hash算法實現有兩個關鍵問題需要解決,一個是用於結點存儲和查找的數據結構的選擇,另一個是結點hash算法的選擇。

首先來談一下一致性hash算法中用於存儲結點的數據結構。通過了解一致性hash的原理,我們知道結點可以想象為是存儲在一個環形的數據結構上(如下圖),結點A、B、C、D按hash值在環形分布上是有序的,也就是說結點可以按hash值存儲在一個有序的隊列裏。如下圖所示,當一個hash值為-2^20的請求點P查找路由結點時,一致性hash算法會按hash值的順時針方向路由到第一個結點上(B),也就是相當於要在存儲結點的有序結構中,按查詢的key值找到大於key值中的最小的那個結點。因此,我們應該選擇一種數據結構,它應該高效地支持結點頻繁地增刪,也必須具有理想的查詢效率。那麽,紅黑樹可以滿足這些要求。紅黑樹是一顆近似平衡的一顆二叉查找樹,因為操作比如插入、刪除和查找某個值的最壞情況時間都要求與樹的高度成比例,這個在高度上的理論上限允許紅黑樹在最壞情況下都是高效的,而不同於普通的二叉查找樹。 因此,我們選擇使用紅黑樹作為結點的存儲結構,除了需要實現紅黑樹基本的插入、刪除、查找的基本功能,我們還應該增加另一個查詢lookup函數,用於查找大於key中最小的結點。

C++map 內部實現方式即為紅黑樹,即直接使用STL::map 就可以。

代碼參考:

一致性哈希算法與C++實現

參考:

一致性哈希算法學習及JAVA代碼實現分析

每天進步一點點——五分鐘理解一致性哈希算法(consistent hashing)

一致性HASH算法

一致性hash與CRUSH算法總結