天天看點

Magent搭建Memcached叢集

Memcached叢集介紹

由于Memcached伺服器與伺服器之間沒有任何通訊,并且不進行任何資料複制備份,是以當任何伺服器節點出現故障時,會出現單點故障,如果需要實作HA,則需要通過另外的方式來解決。

通過Magent緩存代理,防止單點現象,緩存代理也可以做備份,通過用戶端連接配接到緩存代理伺服器,緩存代理伺服器連接配接緩存連接配接伺服器,緩存代理伺服器可以連接配接多台Memcached機器可以将每台Memcached機器進行資料同步。如果其中一台緩存伺服器down機,系統依然可以繼續工作,如果其中一台Memcached機器down掉,資料不會丢失并且可以保證資料的完整性。

搭建Memcached叢集

Magent搭建Memcached叢集

先在三台測試機上安裝好libevent和memcached,啟動memcached執行個體;

然後在51和52上安裝好magent,啟動magent執行個體。

安裝和啟動memcached執行個體

1

2

3

<code>/usr/local/bin/memcached</code> <code>-d -m 256 -u memcached -l 192.168.11.51 -p 11211 -c 1024 -P </code><code>/var/run/memcached/memcached</code><code>.pid</code>

<code>/usr/local/bin/memcached</code> <code>-d -m 256 -u memcached -l 192.168.11.52 -p 11211 -c 1024 -P </code><code>/var/run/memcached/memcached</code><code>.pid</code>

<code>/usr/local/bin/memcached</code> <code>-d -m 256 -u memcached -l 192.168.11.68 -p 11211 -c 1024 -P </code><code>/var/run/memcached/memcached</code><code>.pid</code>

安裝和啟動magent執行個體

筆者在測試magent-0.6.tar.gz時,該版本在與最新版memcached運作下不夠穩定,如下配置以magent-0.5.tar.gz為示例。

1. 安裝magent到/usr/local下:   

4

5

6

<code>cd</code> <code>/usr/local</code>    

<code>mkdir</code> <code>magent    </code>

<code>cd</code> <code>magent    </code>

<code>wget http:</code><code>//memagent</code><code>.googlecode.com</code><code>/files/magent-0</code><code>.5.</code><code>tar</code><code>.gz    </code>

<code>(若無法直接通路,可先下載下傳安裝包後上傳到伺服器上)    </code>

<code>tar</code> <code>zxvf magent-0.5.</code><code>tar</code><code>.gz</code>

2. 修改配置:   

在ketama.h檔案開頭添加    

<code>#ifndef SSIZE_MAX    </code>

<code>#define SSIZE_MAX 32767    </code>

<code>#endif</code>

<code>ln</code> <code>-s </code><code>/usr/lib64/libm</code><code>.so </code><code>/usr/lib64/libm</code><code>.a</code>

<code>/sbin/ldconfig</code>

<code>sed</code> <code>-i </code><code>"s#LIBS = -levent#LIBS = -levent -lm#g"</code> <code>Makefile    </code>

<code>vi</code> <code>Makefile</code>

将    

<code>CFLAGS = -Wall -O2 -g</code>

修改為:    

<code>CFLAGS = -lrt -Wall -O2 -g</code>

儲存

3. 編譯:   

<code>make</code>

輸出如下資訊:    

<code>gcc -lrt -Wall -O2 -g -c -o magent.o magent.c    </code>

<code>gcc -lrt -Wall -O2 -g -c -o ketama.o ketama.c    </code>

<code>gcc -lrt -Wall -O2 -g -o magent magent.o ketama.o -levent –lm</code>

4. 檢視指令幫助:   

<code>.</code><code>/magent</code> <code>–h</code>

7

8

9

10

11

12

13

14

15

<code>memcached agent v0.4 Build-Date: Apr 21 2015 09:21:10    </code>

<code>Usage:    </code>

<code>-h this message    </code>

<code>-u uid    </code>

<code>-g gid    </code>

<code>-p port, default is 11211. (0 to disable tcp support)    </code>

<code>-s ip:port, set memcached server ip and port    </code>

<code>-b ip:port, set backup memcached server ip and port    </code>

<code>-l ip, local bind ip address, default is 0.0.0.0    </code>

<code>-n number, set max connections, default is 4096    </code>

<code>-D don't go to background    </code>

<code>-k use ketama key allocation algorithm    </code>

<code>-f file, unix socket path to listen on. default is off    </code>

<code>-i number, set max keep alive connections for one memcached server, default is 20    </code>

<code>-v verbose</code>

5. 啟動magent執行個體   

<code>/usr/local/magent/magent</code> <code>-u root -n 4096 -l 192.168.11.51 -p 11200 -s 192.168.11.51:11211 -s 192.168.11.52:11211 -b 192.168.11.68:11211    </code>

<code>/usr/local/magent/magent</code> <code>-u root -n 4096 -l 192.168.11.52 -p 11200 -s 192.168.11.51:11211 -s 192.168.11.52:11211 -b 192.168.11.68:11211</code>

測試流程

登入51上的magent,存儲key1到key5:

16

17

18

19

20

21

22

23

24

25

26

<code>[root@mongo01 ~]# telnet 192.168.11.51 11200</code>

<code>Trying 192.168.11.51...</code>

<code>Connected to 192.168.11.51.</code>

<code>Escape character is '^]'.</code>

<code>stats</code>

<code>memcached agent v0.4</code>

<code>matrix 1 -&gt; 192.168.11.51:11211, pool size 0</code>

<code>matrix 2 -&gt; 192.168.11.52:11211, pool size 0</code>

<code>END</code>

<code>set key1 0 0 1</code>

<code>1</code>

<code>STORED</code>

<code>set key2 0 0 2</code>

<code>22</code>

<code>set key3 0 0 3</code>

<code>333</code>

<code>set key4 0 0 4</code>

<code>4444</code>

<code>set key5 0 0 5</code>

<code>55555</code>

<code>quit</code>

<code>Connection closed by foreign host.</code>

登入到51上的memcached,擷取到了key2和key4:

<code>[root@mongo01 ~]# telnet 192.168.11.51 11211</code>

<code>get key1</code>

<code>get key2</code>

<code>VALUE key2 0 2</code>

<code>get key3</code>

<code>get key4</code>

<code>VALUE key4 0 4</code>

<code>get key5</code>

登入到52上的memcached,擷取到了key1、key3和key5:

<code>[root@mongo02 ~]# telnet 192.168.11.52 11211</code>

<code>Trying 192.168.11.52...</code>

<code>Connected to 192.168.11.52.</code>

<code>VALUE key1 0 1</code>

<code>VALUE key3 0 3</code>

<code>VALUE key5 0 5</code>

登入到68上的memcached,擷取到了key1到key5:

<code>[root@szlnmp01 ~]# telnet 192.168.11.68 11211</code>

<code>Trying 192.168.11.68...</code>

<code>Connected to 192.168.11.68.</code>

停掉52的memcached程序,通過51上的magent擷取到了key1到key5:

<code>kill</code> <code>`</code><code>cat</code> <code>/var/run/memcached/memcached</code><code>.pid`</code>

<code>[root@mongo01 magent]# telnet 192.168.11.51 11200</code>

恢複52的memcached程序,通過51上的magent,隻擷取到了key2和key4:

通過以上測試可以得出結論:

1. 通過magent的連接配接池存放的值會分别存在magent代理的所有memcached上去。

2. 如果有一個memcached當機通過magent代理方式還能取到值。

3. 如果memcached修複重新開機後通過magent代理方式取到的值就會為Null,這是由于memcache重新開機後裡邊的值随着memcache服務的停止就消失了(因為在記憶體中),但是magent是通過key進行哈希計算配置設定到某台機器上的,memcache重新開機後會還從這台機器上取值,所有取到的值就為空。

解決辦法:

1. 在每次memcache當機修複後可以寫一個程式把叢集中的其他memcache的所有資訊全給拷貝到目前當機修複後的memcache中。

2. 自己寫代理,當從一個memcached服務上取到的值為Null時再去其他memcached上取值。

注意事項:

magent的調用方式同memcached一樣,用戶端可以不用改代碼即可實作切換到magent模式下。

緩存與DB的同步

比較保險的做法是:查詢的時候從緩存中取,add、updae、delete的時候同時操作緩存與DB。

當然你也可以定時同步緩存與DB的資料,不同的業務應該有不同的選擇。

magent-0.6版本相關的錯誤彙總

産生如下錯誤:   

<code>gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c    </code>

<code>magent.c: In function ‘writev_list’:    </code>

<code>magent.c:729: error: ‘SSIZE_MAX’ undeclared (first use in this function)    </code>

<code>magent.c:729: error: (Each undeclared identifier is reported only once    </code>

<code>magent.c:729: error: for each function it appears in.)    </code>

<code>make: *** [magent.o] Error 1</code>

解決方法:    

再次make    

産生如下錯誤:    

<code>gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o ketama.o ketama.c    </code>

<code>gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o     </code>

<code>usr/lib64/libevent.a /usr/lib64/libm.a     </code>

<code>gcc: /usr/lib64/libevent.a: No such file or directory    </code>

<code>gcc: /usr/lib64/libm.a: No such file or directory    </code>

<code>make: *** [magent] Error 1</code>

<code>ln</code> <code>-s </code><code>/usr/lib64/libm</code><code>.so </code><code>/usr/lib64/libm</code><code>.a    </code>

找到LIBS = /usr/lib64/libevent.a /usr/lib64/libm.a    

按照如下格式修改:    

LIBS = /usr/&lt;libevent的安裝路徑&gt;/libevent.a /usr/lib64/libm.a    

如:LIBS = /usr/lib/libevent.a /usr/lib64/libm.a    

儲存    

<code>gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib/libevent.a /usr/lib64/libm.a     </code>

<code>/usr/lib/libevent.a(event.o): In function `gettime':    </code>

<code>/tmp/libevent-2.0.22-stable/event.c:370: undefined reference to `clock_gettime'    </code>

<code>/usr/lib/libevent.a(event.o): In function `detect_monotonic':    </code>

<code>/tmp/libevent-2.0.22-stable/event.c:340: undefined reference to `clock_gettime'    </code>

<code>collect2: ld returned 1 exit status    </code>

<code>CFLAGS = -Wall -g -O2 -I/usr/local/include $(M64)</code>

<code>CFLAGS = -lrt -Wall -g -O2 -I/usr/local/include $(M64)</code>

輸出為:    

<code>gcc -lrt -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib/libevent.a /usr/lib64/libm.a</code>

<code> </code>

繼續閱讀