一致性雜湊:就是普通取模雜湊演算法的改良版,雜湊函式計算方法不變,只不過是通過構建環狀的 hash 空間代替普通的線性 hash 空間。
考慮到分布式系統每個節點都有可能失效,並且新的節點很可能動態的增加進來,如何保證當系統的節點數目發生變化時仍然能夠對外提供良好的服務,這是值得考慮的,尤其實在設計分布式快取系統時,如果某台伺服器失效,對於整個系統來說如果不採用合適的演算法來保證一致性,那麼快取於系統中的所有資料都可能會失效(即由於系統節點數目變少,客戶端在請求某一物件時需要重新計算其hash值(通常與系統中的節點數目有關),由於hash值已經改變,所以很可能找不到儲存該物件的伺服器節點),因此一致性hash就顯得至關重要,良好的分布式cahce系統中的一致性hash演算法應該滿足以下幾個方面:
平衡性是指雜湊的結果能夠盡可能分布到所有的緩衝中去,這樣可以使得所有的緩衝空間都得到利用。很多雜湊演算法都能夠滿足這一條件。
單調性是指如果已經有一些內容通過雜湊分派到了相應的緩衝中,又有新的緩衝區加入到系統中,那麼雜湊的結果應能夠保證原有已分配的內容可以被對映到新的緩衝區中去,而不會被對映到舊的緩衝集合中的其他緩衝區。簡單的雜湊演算法往往不能滿足單調性的要求,如最簡單的線性雜湊:x = (ax + b) mod (p),在上式中,p表示全部緩衝的大小。不難看出,當緩衝大小發生變化時(從p1到p2),原來所有的雜湊結果均會發生變化,從而不滿足單調性的要求。雜湊結果的變化意味著當緩衝空間發生變化時,所有的對映關係需要在系統內全部更新。而在p2p系統內,緩衝的變化等價於peer加入或退出系統,這一情況在p2p系統中會頻繁發生,因此會帶來極大計算和傳輸負荷。單調性就是要求雜湊演算法能夠應對這種情況。
在分布式環境中,終端有可能看不到所有的緩衝,而是只能看到其中的一部分。當終端希望通過雜湊過程將內容對映到緩衝上時,由於不同終端所見的緩衝範圍有可能不同,從而導致雜湊的結果不一致,最終的結果是相同的內容被不同的終端對映到不同的緩衝區中。這種情況顯然是應該避免的,因為它導致相同內容被儲存到不同緩衝中去,降低了系統儲存的效率。分散性的定義就是上述情況發生的嚴重程度。好的雜湊演算法應能夠盡量避免不一致的情況發生,也就是盡量降低分散性。
負載問題實際上是從另乙個角度看待分散性問題。既然不同的終端可能將相同的內容對映到不同的緩衝區中,那麼對於乙個特定的緩衝區而言,也可能被不同的使用者對映為不同的內容。與分散性一樣,這種情況也是應當避免的,因此好的雜湊演算法應能夠盡量降低緩衝的負荷。
平滑性是指快取伺服器的數目平滑改變和快取物件的平滑改變是一致的。
首先,選擇乙個足夠大的hash空間(一般是 0 ~ 2^32)構成乙個雜湊環。
然後,對於快取集群內的每個儲存伺服器節點計算 hash 值,可以用伺服器的 ip 或 主機名計算得到雜湊值,計算得到的雜湊值就是服務節點在 hash 環上的位置。
最後,對每個需要儲存的資料 key 同樣也計算一次雜湊值,計算之後的雜湊也對映到環上,資料儲存的位置是沿順時針的方向找到的環上的第乙個節點。如果超過2^32仍然找不到伺服器,就會儲存到第一台儲存伺服器節點上。
當快取集群的節點有所增加的時候,普通雜湊演算法會導致原有雜湊對映大面積失效。而一致性雜湊整個環形空間的對映仍然會保持順時針規則,只有一小部分key的歸屬會受到影響。
如下圖所示,當快取服務集群要新增乙個節點node3時,受影響的只有 key3 對應的資料 value3,此時只需把 value3 由原來的節點 node0 遷移到新增節點 node3 即可,其餘節點儲存的資料保持不動。
當快取集群的節點需要刪除的時候(比如節點掛掉),普通雜湊演算法也會導致原有雜湊對映大面積失效。而一致性雜湊整個環形空間的對映仍然會保持順時針規則,同樣只有一小部分key的歸屬會受到影響。
如下圖所示,假設 node2 節點宕機下線,則原來儲存於 node2 的資料 value2 和 value5 ,只需按順時針方向選擇新的儲存節點 node0 存放即可,不會對其他節點資料產生影響。一致性雜湊能把節點宕機造成的影響控制在順時針相鄰節點之間,避免對整個集群造成影響。
若快取集群內的服務節點比較少,就像我們例子中的三個節點,而雜湊環的空間又有很大(一般是 0 ~ 2^32),可能導致較少的服務節點雜湊值聚集在一起。
比如下圖所示這種情況 node0 、node1、node2 聚集在一起,快取資料的 key 雜湊都對映到 node2 的順時針方向,資料按順時針尋找儲存節點就導致全都儲存到 node0 上去,給單個節點很大的壓力!這種情況稱為資料傾斜。
資料傾斜和節點宕機都可能會導致快取雪崩。
資料傾斜導致所有快取資料都打到 node0 上面,有可能會導致 node0 不堪重負被壓垮了,node0 宕機,資料又都打到 node1 上面把 node1 也打垮了,node1 也被打趴傳遞給 node2,這時候故障就像像雪崩時滾雪球一樣越滾越大。
節點宕機比如下圖所示的節點 node2 下線導致原本在node2 的資料壓到 node0 , 在資料量特別大的情況下也可能導致節點雪崩,具體過程就像剛才的分析一樣。
總之,連鎖反應導致的整個快取集群不可用,就稱為節點雪崩。
可以通過「虛擬節點」的方式解決上述兩個問題。
所謂虛擬節點,就是對原來單一的物理節點在雜湊環上虛擬出幾個它的分身節點,這些分身節點稱為「虛擬節點」。打到分身節點上的資料實際上也是對映到分身對應的物理節點上,這樣乙個物理節點可以通過虛擬節點的方式均勻分散在雜湊環的各個部分,解決了資料傾斜問題。
由於虛擬節點分散在雜湊環各個部分,當某個節點宕機下線,他所儲存的資料會被均勻分配給其他各個節點,避免對單一節點突發壓力導致的節點雪崩問題。
下圖左邊是沒做虛擬節點情況下的節點分布,右邊背景色綠色兩個的 node0 節點是 node0 節點的虛擬節點;背景色紅色的 node1 節點是 node1 的虛擬節點。
一致性hash演算法 面試必備 一致性hash演算法
最近公司在招人,我們準備的問題中有一道是關於一致性hash演算法的問題,只有一些面試者能夠回答上來,而且答的也不是很全面,有的面試者只是聽說過,有的連聽都沒聽過,下面我把一致性hash演算法整理一下分享給大家 一致性雜湊演算法在1997年由麻省理工學院的karger等人在解決分布式cache中提出的...
一致性hash演算法虛擬節點 一致性hash演算法
hash 演算法也叫做雜湊演算法,他可以讓任意長度的資料m對映成為長度固定的值h。hash演算法的第乙個作用就是資料的快速儲存與查詢。寫過程式的人都知道,基本上主流的程式語言裡面都有個資料結構叫做map dictionary或者 hash table 它是根據key來直接訪問結果的資料結構。key的...
一致性hash演算法
july部落格16章開始 第一題 全排列,輸入乙個字串,列印出該字串中字元的所有排列 1.個人思路 回溯法建立的排序樹 2.july部落格 遞迴實現,依次固定第乙個字母,後面的交換,和上面描述的使用回溯法相似 c stl 演算法 next permutation的思想,關於next permutat...