1. 程式人生 > 程式設計 >Hash 演演算法一致性

Hash 演演算法一致性

假如你有一個網站,需要用 redis 儲存圖片,圖片名為 key,圖片地址為 value,此時你有4臺 Redis 伺服器來存這些圖片。

使用者要訪問 flowers.png 的圖片,但不知道 flowers.png 的地址在4臺中的哪一臺,如果是去遍歷肯定不科學,這裡就需要用到分散式 hash 演演算法(Distributed Hash)

將圖片的名稱轉成 hash 值,再通過取模得到的值找到 Redis 伺服器。

redis 伺服器號 = hash(檔名) % 伺服器臺數
複製程式碼

WeWork Helper20190806114529

通過計算,可以直接去 Readis 1 號伺服器找到 flowers.png 圖片地址了。

假如此時 Readis 1

伺服器崩潰了,此時的通過 Hash 值取模的方式就失效了,Hash(flowers.png)%3 肯定就不等於 1 了,這時只能對儲存的所有資料進行重新計算分配,然後通過 Hash(flowers.png)%3 找到對應的伺服器。

假如增加一個伺服器 Readis 4,同樣會對儲存的所有資料進行重新計算分配。

由此可以得出結論服務數量變化會導致:1)定位伺服器的計算方式失效。2)儲存的所有資料需要重新計算分配。

用 Hash 一致性演演算法來解決這個問題。

Hash 一致性演演算法(Consistent Hasing)

不再將伺服器編號,而是將伺服器資訊生成一個角度(0~2π),將伺服器定位到一個圓形上。由於伺服器較少,可以將伺服器虛擬幾個節點出來,讓圓上的分佈更均勻,RedisA

虛擬出五個節點 RedisA1RedisA2RedisA3RedisA4RedisA5都代表 RedisA

WeWork Helper20190806040058

如上圖 flowers.png 計算出位於小黑點的位置,那麼按順時針方向就可以找到 RedisA4

假如 RedisA 舵機了,此時 flowers.png 的指向將順移到下個節點 RedisC2,所以 flowers.png 的位置計算方式不會失效,而且只需要重新計算分配與 RedisA 順時針關聯的第一個節點,其他節點保持不變。

WeWork Helper20190806041937

假如新增一個 RedisE 呢?與RedisA 舵機相似,flowers.png 的位置不變,指向順時針離它最近的節點,也就是說新增節點只會與它順時針關聯的第一個節點重新計算分配,其他節點保持不變。

WeWork Helper20190806045947

Reference