一致性hash是什麼?假設有4臺緩存服務器N0,N1,N2,N3
,如今須要存儲數據OBJECT1,OBJECT2,OBJECT3,OBJECT4,OBJECT5,OBJECT5,OBJECT7,OBJECT8
,
咱們須要將這些數據緩存到這4臺服務器上,相應的問題是golang
如何設計數據存放策略?即ObjectX 應該存放在哪臺服務器上?
爲了解決這個問題,咱們有以下幾個思路。緩存
採用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
便可。微信
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
上框架
此時爲了保證數據的準確性,咱們須要
將數據Object2
從N3
遷移到N0
將數據Object5
從N1
遷移到N2
將數據Object6
從N2
遷移到N0
將數據Object7
從N3
遷移到N1
將數據Object8
從N0
遷移到N2
ide
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
則應該存放到節點N3
上idea
此時爲了保證數據的準確性,咱們須要插件
將數據Object2
從N3
遷移到N0
將數據Object5
從N1
遷移到N0
將數據Object6
從N2
遷移到N1
將數據Object7
從N3
遷移到N2
將數據Object8
從N0
遷移到N3
從上述倆種狀況能夠看出,一旦機器數目變化,咱們面臨大量的緩存變化問題,換言之,緩存大部分失效,極可能會致使雪崩。
如今咱們更換以下策略
0<hash(Objectx)%8<=2 ,則存放在N0
2<hash(Objectx)%8<=4 ,則存放在N1
4<hash(Objectx)%8<=6 ,則存放在N2
6<hash(Objectx)%8<=8 ,則存放在N3
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
此時爲了保證數據的準確性,咱們須要
將數據ObjectX
從N3
遷移到N0
,受影響的數據僅僅N3相關的數據。
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
機器越少,則每臺機器上負載將越不均勻,解決這個問題的方法是添加虛擬節點,調整策略,以下,能夠想象,數據越多,分佈越均勻。
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
原理網絡上太多,這裏不作進一步闡述。
開源項目golang go語言後臺管理框架restgo-admin
推薦閱讀
掃微信二維碼實現網站登錄提供體驗地址和源代碼
開源項目golang go語言後臺管理框架restgo-admin
支持手勢觸摸,可左右滑動的日曆插件
你必須知道的18個互聯網業務模型