當網站訪問量達到一定時,如何做Memcached集群,又如何高可用,是接下來要討論的問題。
有這么一段文字來描述“Memcached集群”
Memcached如何處理容錯的?
不處理!:) 在memcached節點失效的情況下,集群沒有必要做任何容錯處理。如果發生了節點失效,應對的措施完全取決於用戶。節點失效時,下面列出幾種方案供您選擇:
* 忽略它! 在失效節點被恢復或替換之前,還有很多其他節點可以應對節點失效帶來的影響。
* 把失效的節點從節點列表中移除。做這個操作千萬要小心!在默認情況下(余數式哈希算法),客戶端添加或移除節點,會導致所有的緩存數據不可用!因為哈希參照的節點列表變化了,大部分key會因為哈希值的改變而被映射到(與原來)不同的節點上。
* 啟動熱備節點,接管失效節點所占用的IP。這樣可以防止哈希紊亂(hashing chaos)。
根據上面的說法,Memcached其中一個節點失效以后,memcached本身是沒有任何策略維持失效轉發的,這對於大型系統是一個無法接受的事實。
舉例說明:
在客戶端連接的部分寫入多個服務器端的ip地址,客戶端將會自動的把緩存數據分布的放在每個不同的機器上,如圖所示:
缺陷說明:
如果其中一個緩存節點的機器down機,那么客戶端存入的緩存數據將會丟失一部分,就是圖中紅色字體描述的“Losed 33% Cache Data”,也就是說那部分數據徹底沒有了!如果是用戶的關鍵性信息那么就玩大了,如圖所示:
解決方案:采用緩存代理服務器
采用 Magent 緩存代理,防止單點現象,緩存代理也可以做備份,通過客戶端連接到緩存代理服務器,緩存代理服務器連接緩存服務器,緩存代理服務器可以連接多台Memcached機器,如下圖所示,配件清單如下:
Magent代理服務器:2台,分別為 192.168.1.2:12000、192.168.1.3:12000
Memcached主服務器:3台,分別為 192.168.1.4:11211、192.168.1.5:11211、192.168.1.6:11211
Memcached備服務器:2台,分別為 192.168.1.5:11211、192.168.1.6:11211
搭建Memcahced服務器:
在 192.168.1.4、192.168.1.5、192.168.1.6、192.168.1.7、192.168.1.8 上分別編譯安裝並運行Memcached ,
搭建Magent代理服務器:
在 192.168.1.2、192.168.1.3 上分別 編譯安裝 magent [CSDN下載 Magent]
#編譯安裝安裝magent到 /usr/local/ 下
cd /usr/local/ mkdir ./magent cd ./magent wget -c http://memagent.googlecode.com/files/magent-0.6.tar.gz tar xzvf ./magent-0.6.tar.gz /sbin/ldconfig sed -i "s#LIBS = -levent#LIBS = -levent -lm#g" Makefile make cp ./magent /usr/bin/magent
注意:編譯的過程中遇到了好幾處錯誤,錯誤解決過程,請參考:
CentOS6.3編譯安裝Memcached集群分布式緩存代理Magent-0.6出錯匯總
magent命令詳解:
-h this message
-u uid
-g gid
-p port, default is 11211. (0 to disable tcp support)
-s ip:port, set memcached server ip and port
-b ip:port, set backup memcached server ip and port
-l ip, local bind ip address, default is 0.0.0.0
-n number, set max connections, default is 4096
-D do not go to background
-k use ketama key allocation algorithm
-f file, unix socket path to listen on. default is off
-i number, max keep alive connections for one memcached server, default is 20
-v verbose
在 192.168.1.2、192.168.1.3 上分別運行 magent:
magent -u root -n 51200 -l 192.168.1.2 -p 12000 -s 192.168.1.4:11211 -s 192.168.1.5:11211 -s 192.168.1.6:11211 -b 192.168.1.7:11211 -b 192.168.1.8:11211
測試緩存數據的分布情況:
以前,我們用PHP連接多台Memcached服務器,做分布式緩存時,參考代碼如下:
$memcache = new Memcache; $memcache->addServer('localhost', 11211); $memcache->addServer('localhost', 11212); $memcache->addServer('localhost', 11213); for ($i = 0; $i < 1000; $i++) { $memcache->set($i, $i, 0, 1000); }
現在,代碼還是那段代碼,只不過連接的主機不是Memcached服務器了,而是 Magent代理服務器,給 addServer()方法傳參時,傳入的是Magent主機IP與端口!測試代碼如下:
$mem = new \Memcache(); $host = '192.168.1.2'; $port = '12000 '; $mem->connect($host, $port); $key1 = 'snsgou1'; $value1 = '1'; $mem->add($key1, $value1); $key2 = 'snsgou2'; $value2 = '2'; $mem->add($key2, $value2); $key3 = 'snsgou3'; $value3 = '3'; $mem->add($key3, $value3); $key4 = 'snsgou4'; $value4 = '4'; $mem->add($key4, $value4); $key5 = 'snsgou5'; $value5 = '5'; $mem->add($key5, $value5); $key6 = 'snsgou6'; $value6 = '6'; $mem->add($key6, $value6);
說明:
1、PHP連接magent,把緩存key1交給magent,magent根據自身的配置參數,再加上一定的哈希算法,會計算出key1存在3台主Memcached服務器的某一台上,然后以同樣的算法,將key1也在2台備用的Memcached服務器中的某一台上,再存一份數據。即,主服務器是分布式存儲的,同時,從服務器也是分布式存儲的;
2、在PHP獲取緩存數據key1時,magent一旦得知數據所存的那台主Memcached服務器掛掉了,它就會轉向從備用的Memcached服務器中獲取數據。注意:服務器的定位選擇算法跟存的時候是一樣的。
3、有個缺陷,當 down 掉的那台主Memcached服務器重新恢復正常后,Memcahed里是沒有數據的,即數據全部丟失,但此時 備用的Memcached服務器 又不會將數據同步到 主服務器。
4、通過Memcached管理軟件MemAdmin(點擊下載)去查看上述數據分布情況,如下:
192.168.1.4 存有 snsgou6,snsgou3
192.168.1.5 存有 snsgou4,snsgou1
192.168.1.6 存有 snsgou5,snsgou2
192.168.1.7 存有 snsgou5,snsgou3,snsgou1
192.168.1.8 存有 snsgou4,snsgou6,snsgou2
5、PHP連接代理的時候,最好每次隨機性只連一台,這樣,一旦某台代理掛了(即連不上),可切換連另外一台代理服務器。而隨機性地去連,又保證了一定的負載均衡。
6、本來我打算通過修改配置文件php.ini,使PHP系統的會話(Session)通過Magent代理保存到Memcached服務器中,修改方式參考:PHP如何將session保存到memcached中?如何分布式保存PHP session
但是呢,把Mangent代理服務器IP及端口貼到php.ini后(已重啟了相關服務器),發現會話根本沒保存到Memcached中,即PHP底層不識別Magent代理,郁悶!!!
參考:
http://www.javabloger.com/article/memcached-cluster-error-msag.html
[張宴]Memcached的代理服務器軟件:magent使用小記[原創]