1. 程式人生 > 其它 >一致性雜湊的簡單理解

一致性雜湊的簡單理解

一致性Hash是一種特殊的Hash演算法,由於其均衡性、永續性的對映特點,被廣泛的應用於負載均衡領域。

非常簡單的Hash演算法Group = Key % N來實現請求的負載均衡,通過對叢集數量 N 取模,得到該 key 應該查詢、儲存的伺服器節點

問題1:當快取伺服器數量發生變化時,會引起快取的雪崩,可能會引起整體系統壓力過大而崩潰(大量快取同一時間失效)。

問題2:當快取伺服器數量發生變化時,幾乎所有快取的位置都會發生改變,

優化

1.引入雜湊環,解決縮容、擴容的成本問題

通過構建環狀的Hash空間代替線性Hash空間。Group_t = Key % NEW_Nhash環空間很大(NEW_N一般是 0 ~ 2^32),給每個Key計算Hash,然後沿著順時針的方向找到環上的第一個節點,就是該Key儲存對應的叢集。

當擴容或縮容時,只會影響兩個伺服器節點之間的 key,而不會影響全部的 key。將代價降低。

比如刪除叢集節點 A,只會影響 key1,key2 而其他的 key 不受影響

2.引入虛擬節點,解決資料傾斜的問題

“虛擬節點”是”實際節點”(實際的物理伺服器)在hash環上的複製品,一個實際節點可以對應多個虛擬節點。 將虛擬節點隨機的分佈在雜湊環上 這樣就不會使得過多的 key 命中同一個節點,緩解叢集壓力。

如何優雅縮擴容

1.高頻Key預熱(LRU

維護一份高頻訪問Key的列表,新的叢集在啟動時根據這個列表提前拉取對應Key的快取值進行預熱,便可以大大減少因為新增叢集而導致的Key失效。

2.歷史Hash環保留

舉例,假設我們原有3個叢集,現在要擴充套件到6個叢集,這就意味著原有50%的Key都會失效(被轉移到新節點上),如果我們維護擴容前和擴容後的兩個Hash環,在擴容後的Hash環上找不到Key的儲存時,先轉向擴容前的Hash環尋找一波,如果能夠找到就返回對應的值並將該快取寫入新的節點上,找不到時再透過快取

一致性 hash 優化

先說缺陷

整個分散式快取需要一個路由服務來做負載均衡,存在單點問題(如果路由服務掛了,整個快取也就涼了)

Hash環上的節點非常多或者更新頻繁時,查詢效能會比較低下

優化

1.使用HashSlot(分治思想)

類似於Hash環,Redis Cluster採用HashSlot來實現Key值的均勻分佈和例項的增刪管理。

首先預設分配了16384個Slot(這個大小正好可以使用2kb的空間儲存),每個Slot相當於一致性Hash環上的一個節點。接入叢集的所有例項將均勻地佔有這些Slot,而最終當我們Set一個Key時,使用CRC16(Key) % 16384來計算出這個Key屬於哪個Slot,並最終對映到對應的例項上去。

2.P2P節點尋找

實現去中心化的訪問,也就是說無論訪問叢集中的哪個節點,你都能夠拿到想要的資料。其實這有點類似於路由器的路由表,具體說來就是:

  • 每個節點都儲存有完整的HashSlot - 節點對映表,也就是說,每個節點都知道自己擁有哪些Slot,以及某個確定的Slot究竟對應著哪個節點。
  • 無論向哪個節點發出尋找Key的請求,該節點都會通過CRC(Key) % 16384計算該Key究竟存在於哪個Slot,並將請求轉發至該Slot所在的節點。