1.取模算法
這種算法非常的簡單,就是根據服務器台數的余數進行分散,求得整數值的hash值,再除以服務器的台數,根據其余數來選擇服務器,將server的hash值與server的總台數進行求余,即hash%N。
但是在這種算法對緩存命中率的影響下:
我們假設有8台服務器,運行中突然down了一台,則求余的底數變成了7,那么其產生的結果就完全變了
一般地,我們從數學上歸納之:
有N台服務器,變成了N-1台服務器,所以命中率在服務器down的短期內,急劇下降至1/(N-1),所以服務器越多,則down機的后果越嚴重
2.一致性hash算法
為了解決上述取模算法遇到的問題,我們可以使用另一種分布式算法,即一致性hash算法,所謂的一致性hash算法,就是把服務器的各個節點放在鍾表的各個時刻上,同時,我們也將要存儲的key也映射到鍾表的某個時刻上,該key延鍾表順時針走,碰到第一個比他小的節點之后,則key就落在這台服務器上
補充:利用crc32()函數可以將key值轉換成整數
當某個節點down后,只影響該節點順時針之后的1個節點,而其他節點不受影響
我們通過上圖看到,6號節點down后,所有的壓力都轉移到7號節點上,造成了7號節點服務器的壓力特別的大,那我們考慮是否能夠將6號節點的壓力注意到其余的節點上?
所以我們引入了虛擬節點的概念:
虛擬節點-N個真實節點,把每個真實節點映射成M個虛擬節點, 再把M*N個虛擬節點,散列在圓環上. 各真實節點對應的虛擬節點相互交錯分布,這樣某個真實節點down后,則把其影響平均分擔到其他所有節點上