關於一致性hash,這多是全網最形象生動最容易理解的文檔,想作架構師的你來了解一下

問題提出

一致性hash是什麼?假設有4臺緩存服務器N0,N1,N2,N3,如今須要存儲數據OBJECT1,OBJECT2,OBJECT3,OBJECT4,OBJECT5,OBJECT5,OBJECT7,OBJECT8,
咱們須要將這些數據緩存到這4臺服務器上,相應的問題是golang

如何設計數據存放策略?即ObjectX 應該存放在哪臺服務器上?

爲了解決這個問題,咱們有以下幾個思路。緩存

1. 餘數hash方案

採用hash(Objectx)%4來肯定服務器節點

假設 hash(OBJECT1)=2,由 2%4=2,可知,Object1則應該存放到節點N2
假設 hash(OBJECT2)=3,由 3%4=3,可知,Object2則應該存放到節點N3
假設 hash(OBJECT3)=1,由 1%4=1,可知,Object3則應該存放到節點N1
假設 hash(OBJECT4)=0,由 1%4=1,可知,Object4則應該存放到節點N0
假設 hash(OBJECT5)=5,由 5%4=1,可知,Object5則應該存放到節點N1
假設 hash(OBJECT6)=6,由 6%4=2,可知,Object6則應該存放到節點N2
假設 hash(OBJECT7)=7,由 7%4=3,可知,Object7則應該存放到節點N3
假設 hash(OBJECT8)=8,由 8%4=0,可知,Object8則應該存放到節點N0服務器

假設咱們須要讀取Object3的數據,則由hash(object3)=1可知,咱們只須要訪問節點N1便可。微信

1.1 如今假設N3突然故障下線

咱們面臨緩存從新構造的問題網絡

採用hash(Objectx)%3來肯定服務器節點

假設 hash(OBJECT1)=2,由 2%3=2,可知,Object1則應該存放到節點N2
假設 hash(OBJECT2)=3,由 3%3=0,可知,Object2則應該存放到節點N0
假設 hash(OBJECT3)=1,由 1%3=1,可知,Object3則應該存放到節點N1
假設 hash(OBJECT4)=0,由 0%3=0,可知,Object4則應該存放到節點N0
假設 hash(OBJECT5)=5,由 5%3=2,可知,Object5則應該存放到節點N2
假設 hash(OBJECT6)=6,由 6%3=0,可知,Object6則應該存放到節點N0
假設 hash(OBJECT7)=7,由 7%3=1,可知,Object7則應該存放到節點N1
假設 hash(OBJECT8)=8,由 8%3=2,可知,Object8則應該存放到節點N2框架

此時爲了保證數據的準確性,咱們須要
將數據Object2N3遷移到N0
將數據Object5N1遷移到N2
將數據Object6N2遷移到N0
將數據Object7N3遷移到N1
將數據Object8N0遷移到N2ide

1.2 如今假設咱們添加一臺新的服務器N4

咱們面臨緩存從新構造的問題網站

採用hash(Objectx)%5來肯定服務器節點

假設 hash(OBJECT1)=2,由 2%5=2,可知,Object1則應該存放到節點N2
假設 hash(OBJECT2)=3,由 3%5=3,可知,Object2則應該存放到節點N3
假設 hash(OBJECT3)=1,由 1%5=1,可知,Object3則應該存放到節點N1
假設 hash(OBJECT4)=0,由 0%5=0,可知,Object4則應該存放到節點N0
假設 hash(OBJECT5)=5,由 5%5=0,可知,Object5則應該存放到節點N0
假設 hash(OBJECT6)=6,由 6%5=1,可知,Object6則應該存放到節點N1
假設 hash(OBJECT7)=7,由 7%5=2,可知,Object7則應該存放到節點N2
假設 hash(OBJECT8)=8,由 8%5=3,可知,Object8則應該存放到節點N3idea

此時爲了保證數據的準確性,咱們須要插件

將數據Object2N3遷移到N0
將數據Object5N1遷移到N0
將數據Object6N2遷移到N1
將數據Object7N3遷移到N2
將數據Object8N0遷移到N3

從上述倆種狀況能夠看出,一旦機器數目變化,咱們面臨大量的緩存變化問題,換言之,緩存大部分失效,極可能會致使雪崩。

2.一致性hash方案

如今咱們更換以下策略

0<hash(Objectx)%8<=2 ,則存放在 N0
2<hash(Objectx)%8<=4 ,則存放在 N1
4<hash(Objectx)%8<=6 ,則存放在 N2
6<hash(Objectx)%8<=8 ,則存放在 N3

2.1 如今假設N3突然故障下線

咱們面臨緩存從新構造的問題,調整策略以下

0<hash(Objectx)%8<=2 ,則存放在 N0
2<hash(Objectx)%8<=4 ,則存放在 N1
4<hash(Objectx)%8<=6 ,則存放在 N2
6<hash(Objectx)%8<=8 ,則存放在 N0

此時爲了保證數據的準確性,咱們須要
將數據ObjectXN3遷移到N0,受影響的數據僅僅N3相關的數據。

2.2 如今假設咱們添加一臺新的服務器N4

咱們面臨緩存從新構造的問題,調整策略以下

0<hash(Objectx)%8<=2 ,則存放在 N0
2<hash(Objectx)%8<=4 ,則存放在 N1
4<hash(Objectx)%8<=5 ,則存放在 N2
5<hash(Objectx)%8<=6 ,則存放在 N4
6<hash(Objectx)%8<=8 ,則存放在 N3

此時爲了保證數據的準確性,咱們須要
將數據從N2複製到N4,受影響的僅僅N2相關的用戶。

比較上述倆種作法,可見方案2更優. 方案2就是一致性hash

2.3 缺點

機器越少,則每臺機器上負載將越不均勻,解決這個問題的方法是添加虛擬節點,調整策略,以下,能夠想象,數據越多,分佈越均勻。

0<hash(Objectx)%8<=1 ,則存放在 N0
1<hash(Objectx)%8<=2 ,則存放在 N1
2<hash(Objectx)%8<=3 ,則存放在 N2
3<hash(Objectx)%8<=4 ,則存放在 N3
4<hash(Objectx)%8<=5 ,則存放在 N0
5<hash(Objectx)%8<=6 ,則存放在 N1
6<hash(Objectx)%8<=7 ,則存放在 N2
7<hash(Objectx)%8<=8 ,則存放在 N3

3. 一致性Hash原理

原理網絡上太多,這裏不作進一步闡述。

推薦閱讀

掃微信二維碼實現網站登錄提供體驗地址和源代碼

開源項目golang go語言後臺管理框架restgo-admin

支持手勢觸摸,可左右滑動的日曆插件

你必須知道的18個互聯網業務模型

推薦閱讀
掃微信二維碼實現網站登錄提供體驗地址和源代碼
開源項目golang go語言後臺管理框架restgo-admin
支持手勢觸摸,可左右滑動的日曆插件
你必須知道的18個互聯網業務模型

相關文章
相關標籤/搜索