(二十)高併發redis學習筆記:hash slot算法淺談

1、redis和hash算法的關係

主要是redis cluster的時候,對於請求,我們不能說隨機的打到一臺機器上,這樣要是第一次寫到A機器,第二次讀的時候,讀的是B機器,那麼就會發生讀不到的情況,這樣緩存不就失去意義了麼?

所以redis中hash算法的可以簡單理解爲,想辦法如何讓同一個請求,每一次都打到同一個機器上,不同請求分佈到不同的機器上。

2、hash算法的演進

2.1 最初hash算法

簡單來說,就是hash取模,假設有N臺機器,那麼通過:

index = hash(key) % N

計算出來的index就是機器的序號,這樣做簡單明瞭,但是也是有弊端的,那就N如果變化了,會發生一些意外情況。

假設現在有3臺緩存機器,A,B,C,機器分別分佈在上面,此時,C宕機了,那麼所有值錢打到C上面的緩存都會找不到,假設我們發現的,手動把N調整了:

調整前:
A:  key:0,3,5
B:  key:1,4,7
C:  key:2,5,8

調整後:
A: key:0,2,4,6,8
B: key:1,3,5,7,9

舉個栗子,之前key爲3是是寫在A上面的,現在計算出來key的hash是在B上面,這樣也會導致查不到,如果量很大的情況就會導致緩存雪崩。
如果添加一個D也是類似,需要很多映射都已經錯亂了,需要重新映射,那麼就存在大量的緩存重建了。

2.2 一致性hash算法

從上面我們可以知道,根本的原因就是N會變化,我們需要在N變化的時候,影響更少量的數據。
於是就有人想出了的概念,一致性hash算法。

一致性哈希算法在1997年由麻省理工學院的Karger等人在解決分佈式Cache中提出的,設計目標是爲了解決因特網中的熱點(Hot spot)問題,初衷和CARP十分類似。一致性哈希修正了CARP使用的簡單哈希算法帶來的問題,使得DHT可以在P2P環境中真正得到應用。

舉個栗子,將hash值得範圍設置爲0-2^32,假設他們分佈在一個圓環上,然後有三臺服務器A,B,C,那麼也均勻分佈圓環上。會計算key的hash值,落在圓環上,然後順時針找到第一個節點,落在上面。

這樣一來,要是A節點掛了,怎麼辦?
A節點掛了,那麼原來的落在A節點的部分,會找到C,落在C上面,也就隻影響直線A節點的那部分,就是1/3.

如果是加入節點的話,那麼新的服務器直接掛在圓環的一個位置上,只會影響新的服務器到圓環漆面那一臺服務器的部分數據。
由此可以看出,一致性hash算法,不管增減節點,其實都是影響一部分數據,有較高的容錯性和拓展性。

但是這樣做,還會有一個問題,就是熱點數據的數據傾斜問題,假設只有兩臺機器,但是大部分的數據hash之後都落在了A節點的區間。

那這樣就只有少數的會落到B節點上面,這樣數據就會有可能發生嚴重的傾斜,所以就引入了虛擬節點的機制。
所謂虛擬節點,即對每一個節點計算多個hash,每個計算結果位置都放一個服務節點,但是是虛擬的,一般是服務器ip或者主機+編號實現。例如上面的A,B節點,增加虛擬節點,A1,A2,B1,B2:

這樣一來,key hash之後落的位置不變,但是如果定位到A,A1,A2都會定位到A上面,多了從虛擬節點到實際節點的映射,這樣可以解決數據節點少的時候數據傾斜的問題。一般情況下,我們的虛擬節點大小都是大於等於32.
memcached也是使用了一致性hash算法。

2.3 redis的 hash slot算法

redis沒有使用上面說的一致性hash算法,而是使用了自己的hash slot算法,也是爲了在多個master節點的時候,數據如何分佈到這些節點上去,解決這個問題。
redis中hash提出槽的概念,也就是把數據hash分成多個槽,先放着。每個節點呢,相當於一個槽,就可以分得一部分hash值,對應hash值的數據就存在上面。
在redis cluster架構下,每個redis要放開兩個端口號,比如一個是6379,另外一個就是加10000的端口號,比如16379,16379端口號是用來進行節點間通信的,也就是cluster bus的東西,集羣總線。cluster bus的通信,用來進行故障檢測,配置更新,故障轉移授權。
cluster bus用了另外一種二進制的協議,主要用於節點間進行高效的數據交換,佔用更少的網絡帶寬和處理時間。

redis cluster有固定的16384個hash slot,對每個key計算CRC16值,然後對16384取模,可以獲取key對應的hash slot。

redis cluster中每個master都會持有部分slot,比如有3個master,那麼可能每個master持有5000多個hash slot

hash slot讓node的增加和移除很簡單,增加一個master,就將其他master的hash slot移動部分過去,減少一個master,就將它的hash slot移動到其他master上去。

移動hash slot的成本是非常低的,這個是可以自動移動的,不需要手動操作。

在客戶端的api,可以對指定的數據,讓他們走同一個hash slot,通過hash tag來實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章