在伺服器數量不發生改變時,普通的hash分布可以很好地運作。當伺服器的數量發生改變時,問題就出來了,試想,增加一台伺服器時,同乙個key經過hash之後,與伺服器取模的結果跟沒增加伺服器之前的結果會不一樣,這就導致之前儲存的資料丟失。為了把丟失的資料減少到最少,可以採用一致性hash演算法。
一致性hash演算法分為6個步驟:
步驟1:
將乙個32位整數0~2^32 -1想象成乙個環,將0作為圓環的頭,2^32 -1作為圓環的尾,把它連線起來。當然這只是想象。
步驟2:
通過hash函式把key處理成整數。
function
mhash
($key));
$i++;
}return
$hash & 0x7fffffff;
}
$key1 = mhash("key1");
$key2 = mhash("key2");
$key3 = mhash("key3");
$key4 = mhash("key4");
把key處理成整數後,就可以在環中找到乙個位置與之對應,如下圖
步驟3:
把memcached群對映到環上,使用hash函式處理伺服器所使用的ip位址。
假如有3臺伺服器,分別使用ip(127.0.0.1),ip(127.0.0.2),ip(127.0.0.3),使用下面的方法對映到環上。
$server1 = mhash("127.0.0.1");
$server2 = mhash("127.0.0.2");
$server3 = mhash("127.0.0.3");
步驟4:把資料對映 到伺服器上
沿著環順時針方向的key出發,知道遇到下乙個伺服器為止,把key對應的資料儲存到這個伺服器上。根據上面的方法,key4和key3儲存到server2上,key2儲存到server1上,key1儲存到server3上。
步驟5:移除伺服器
考慮一下,如果server2伺服器崩潰了,那麼受最大影響的僅是沿著server2逆時針出發直到下乙個伺服器之間的資料,也就是對映到server2上的那些資料。然後依照規則,將server2伺服器上的資料移植下乙個伺服器上即可。
在上例中,需要進行變動的有key3和key4對應的資料,把這些資料重新對映到server1上即可。
步驟6:新增伺服器。
再考慮一下,如果要新增乙個伺服器server4,用之前的方法把它對映到key3和key4之間,這時受到的影響是沿著server4逆時針出發直至遇到下乙個伺服器之間的資料,把這些資料重新對映到server4上即可。
在這裡僅需要變動的只有key4對應的資料,將其重新對映到server4上即可。
使用php實現一致性hash分布演算法的**如下:(注:個人理解所編寫,並不權威)
Memcached 和 Redis 分布式鎖方案
分布式快取,能解決單台伺服器記憶體不能無限擴張的瓶頸。在分布式快取的應用中,會遇到多個客戶端同時爭用的問題。這個時候,需要用到分布式鎖,得到鎖的客戶端才有操作許可權。memcached 和 redis 是常用的分布式快取構建方案,下面列舉下基於memcached 和 redis 分布式鎖的實現方法。...
Memcached和Redis分布式鎖方案例項講解
分布式快取,能解決單台伺服器記憶體不能無限擴張的瓶頸。在分布式快取的應用中,會遇到多個客戶端同時爭用的問題。這個時候,需要用到分布式鎖,得到鎖的客戶端才有操作許可權。memcached 和 redis 是常用的分布式快取構建方案,下面列舉下基於memcached 和 redis 分布式鎖的實現方法。...
Memcached 分布式快取
memcached是什麼?memcached 是乙個高效能的分布式記憶體物件快取系統,用於動態web應用以減輕資料庫負載。它通過在記憶體中快取資料和物件來減少讀取資料庫的次數,從而提供動態 資料庫驅動 的速度。memcached基於乙個儲存鍵 值對的hashmap。其守護程序 daemon 是用c寫...