memcache分布式部署的原理分析


下面本文章來給各位同學介紹memcache分布式部署的原理分析,希望此文章對你理解memcache分布式部署會有所幫助哦。
 

今天在封裝memcache操作類庫過程中,意識到一直以來對memcache的使用都是局限在單台服務器的情況下,還沒有使用到memcache的分布式部署。雖然知道memcache的分布式是怎么回事,但是為了更加深入的理解,還是通過谷歌搜索了這方面的相關資料。

下面是精摘於網絡的一些關於 memcache分布式部署 的資料。

memcache分布式部署是什么呢?下面通過一個例子來認識一下:

假設memcached服務器有node1~node3三台, 應用程序要保存鍵名為“tokyo”“kanagawa”“chiba”“saitama”“gunma” 的數據。

memcache分布式部署

首先向memcached中添加“tokyo”。將“tokyo”傳給客戶端程序庫后, 客戶端實現的算法就會根據“鍵”來決定保存數據的memcached服務器。 服務器選定后,即命令它保存“tokyo”及其值。

memcache分布式部署

同樣,“kanagawa”“chiba”“saitama”“gunma”都是先選擇服務器再保存。

接下來獲取保存的數據。獲取時也要將要獲取的鍵“tokyo”傳遞給函數庫。 函數庫通過與數據保存時相同的算法,根據“鍵”選擇服務器。 使用的算法相同,就能選中與保存時相同的服務器,然后發送get命令。 只要數據沒有因為某些原因被刪除,就能獲得保存的值。

memcache分布式部署

這樣,將不同的鍵保存到不同的服務器上,就實現了memcached的分布式。 memcached服務器增多后,鍵就會分散,即使一台memcached服務器發生故障無法連接,也不會影響其他的緩存,系統依然能繼續運行。

下面我們具體介紹一下 Consistent hashing算法

Consistent Hashing的簡單說明

Consistent Hashing

首先求出memcached服務器(節點)的哈希值, 並將其配置到0~2SUP(32)的圓(continuum)上。 然后用同樣的方法求出存儲數據的鍵的哈希值,並映射到圓上。 然后從數據映射到的位置開始順時針查找,將數據保存到找到的第一個服務器上。 如果超過2SUP(32)仍然找不到服務器,就會保存到第一台memcached服務器上。

從上圖的狀態中添加一台memcached服務器。余數分布式算法由於保存鍵的服務器會發生巨大變化 而影響緩存的命中率,但Consistent Hashing中,只有在continuum上增加服務器的地點逆時針方向的 第一台服務器上的鍵會受到影響。

Consistent Hashing

因此,Consistent Hashing最大限度地抑制了鍵的重新分布。 而且,有的Consistent Hashing的實現方法還采用了虛擬節點的思想。 使用一般的hash函數的話,服務器的映射地點的分布非常不均勻。 因此,使用虛擬節點的思想,為每個物理節點(服務器) 在continuum上分配100~200個點。這樣就能抑制分布不均勻, 最大限度地減小服務器增減時的緩存重新分布。

下面再介紹一下虛擬節點

Consistent hashing算法在服務節點太少時,容易因為節點分部不均勻而造成數據傾斜問題。例如我們的系統中有兩台 server,其環分布如下:

虛擬節點

此時必然造成大量數據集中到Server 1上,而只有極少量會定位到Server 2上。為了解決這種數據傾斜問題,一致性哈希算法引入了虛擬節點機制,即對每一個服務節點計算多個哈希,每個計算結果位置都放置一個此服務節點,稱為虛擬節點。

具體做法可以在服務器ip或主機名的后面增加編號來實現。例如上面的情況,我們決定為每台服務器計算三個虛擬節點,於是可以分別計算“Memcached Server 1#1”、“Memcached Server 1#2”、“Memcached Server 1#3”、“Memcached Server 2#1”、“Memcached Server 2#2”、“Memcached Server 2#3”的哈希值,於是形成六個虛擬節點:

虛擬節點

同時數據定位算法不變,只是多了一步虛擬節點到實際節點的映射,例如定位到“Memcached Server 1#1”、“Memcached Server 1#2”、“Memcached Server 1#3”三個虛擬節點的數據均定位到Server 1上。這樣就解決了服務節點少時數據傾斜的問題。在實際應用中,通常將虛擬節點數設置為32甚至更大,因此即使很少的服務節點也能做到相對均勻的數據分布,避免出現雪崩的情況。

例子

啟動Memcache服務,比如這樣

 代碼如下 復制代碼

/usr/local/bin/memcached -d -p 11213 -u root -m 10 -c 1024 -t 8 -P /tmp/memcached.pid 
 /usr/local/bin/memcached -d -p 11214 -u root -m 10 -c 1024 -t 8 -P /tmp/memcached.pid 
 /usr/local/bin/memcached -d -p 11215 -u root -m 10 -c 1024 -t 8 -P /tmp/memcached.pid 

啟動三個只使用10M內存以方便測試。


分布式部署
PHP的PECL擴展中的memcache實際上在2.0.0的版本中就已經實現多服務器支持,現在都已經2.2.5了。請看如下代碼

 代碼如下 復制代碼

$memcache = new Memcache; 
 $memcache->addServer('localhost', 11213); 
 $memcache->addServer('localhost', 11214); 
 $memcache->addServer('localhost', 11215); 
 $memStats = $memcache->getExtendedStats(); 
 print_r($memStats); 

通過上例就已經實現Memcache的分布式部署,是不是非常簡單。

分布式系統的良性運行
在Memcache的實際使用中,遇到的最嚴重的問題,就是在增減服務器的時候,會導致大范圍的緩存丟失,從而可能會引導數據庫的性能瓶頸,為了避免出現這種情況,請先看Consistent hashing算法,中文的介紹可以參考這里,通過存取時選定服務器算法的改變,來實現。

修改PHP的Memcache擴展memcache.c的源代碼中的

 代碼如下 復制代碼

"memcache.hash_strategy" = standard 

 代碼如下 復制代碼
"memcache.hash_strategy" = consistent 

重新編譯,這時候就是使用Consistent hashing算法來尋找服務器存取數據了。

有效測試數據表明,使用Consistent hashing可以極大的改善增刪Memcache時緩存大范圍丟失的情況。

 代碼如下 復制代碼
NonConsistentHash: 92% of lookups changed after adding a target to the existing 10
NonConsistentHash: 90% of lookups changed after removing 1 of 10 targets
ConsistentHash: 6% of lookups changed after adding a target to the existing 10
ConsistentHash: 9% of lookups changed after removing 1 of 10 targets


總結:

在動態分布式緩存系統里哈希算法承擔着系統架構上的關鍵點。 使用分布更合理的算法可以使得多個服務節點間的負載相對均衡,可以最大程度的避免資源的浪費以及服務器過載。 使用一致性哈希算法,可以最大程度的降低服務硬件環境變化帶來的數據遷移代價和風險。 使用更合理的配置策略和算法可以使分布式緩存系統更加高效穩定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM