1. 程式人生 > 程式設計 >面試又被問到一致性 Hash 演演算法?這樣回答秒殺面試官!

面試又被問到一致性 Hash 演演算法?這樣回答秒殺面試官!

程式設計改變世界
程式設計改變世界

資料分片

✔︎ 先讓我們看一個例子吧

我們經常會用 Redis 做快取,把一些資料放在上面,以減少資料的壓力。

當資料量少,訪問壓力不大的時候,通常一臺Redis就能搞定,為了高可用,弄個主從也就足夠了;

當資料量變大,併發量也增加的時候,把全部的快取資料放在一臺機器上就有些吃力了,畢竟一臺機器的資源是有限的,通常我們會搭建叢集環境,讓資料儘量平均的放到每一臺 Redis 中,比如我們的叢集中有 4 臺Redis。

那麼如何把資料儘量平均地放到這 4 臺Redis中呢?最簡單的就是取模演演算法:

hash( key ) % N,N 為 Redis 的數量,在這裡 N = 4 ;

資料分片
資料分片

看起來非常得美好,因為依靠這樣的方法,我們可以讓資料平均儲存到 4 臺 Redis 中,當有新的請求過來的時候,我們也可以定位資料會在哪臺 Redis 中,這樣可以精確地查詢到快取資料。

資料分片會遇到的問題

但是 4 臺 Redis 不夠了,需要再增加 4 臺 Redis ;

那麼這個求餘演演算法就會變成:hash( key ) % 8 ;

分片數量改變
分片數量改變

那麼可以想象一下,當前大部分快取的位置都會是錯誤的,極端情況下,就會造成 快取雪崩

一致性 Hash 演演算法

一致性 Hash 演演算法可以很好地解決這個問題,它的大概過程是這樣的:

把 0 作為起點,2^32-1 作為終點,畫一條直線,再把起點和終點重合,直線變成一個圓,方向是順時針從小到大。

0 的右側第一個點是 1 ,然後是 2 ,以此類推。

對三臺伺服器的 IP 或其他關鍵字進行 hash 後對 2^32 取模,這樣勢必能落在這個圈上的某個位置,記為 Node1、Node2、Node3。

先畫一個圈圈
先畫一個圈圈

然後對資料 key 進行相同的操作,勢必也會落在圈上的某個位置;然後順時針行走,可以找到某一個 Node,這就是這個 key 要儲存的伺服器。

資料順時針找到對應的 Redis 節點
資料順時針找到對應的 Redis 節點

如果增加一臺伺服器或者刪除一臺伺服器,只會影響 部分資料。

節點數量改變,影響部分資料
節點數量改變,影響部分資料

但如果節點太少或分佈不均勻的時候,容易造成 資料傾斜,也就是大部分資料會集中在某一臺伺服器上。

資料傾斜
資料傾斜

為瞭解決資料傾斜問題,一致性 Hash 演演算法提出了【虛擬節點】

,會對每一個服務節點計算多個雜湊,然後放到圈上的不同位置。

虛擬節點
虛擬節點

當然我們也可以發現,一致性 Hash 演演算法,也只是 解決大部分資料的問題

會點程式碼的大叔 | 文【原創】


敬請關注會點程式碼的大叔
敬請關注會點程式碼的大叔