Memcache 高可用集群之magent

来源:互联网 发布:mysql count用法 编辑:程序博客网 时间:2024/05/19 20:40
Magent 是一款开源的 Memcached 代理服务器软件,使用它可以搭建高可用性的集群应用的 Memcached 服务 ,备份 Memcached 数据,尽管 Memcached 服务挂掉,前端也能获取到数据,客户端先连到 Magent 代理服务器 ,然后Magent 代理服务器 在可以连接多台 Memcached 服务器,然后可以进行数据的保存和备份数据。这样数据就不会丢失,保存了数据完整性。
项目地址:
http://code.google.com/p/memagent
https://github.com/wangmh/memagent

一、整体架构

从图中可以看到有两个magent节点,两个memcached节点,每个magent节点又分别代理两个memcached节点,应用系统端使用magent pool来调用memcache进行存储。硬件结构为两台linux服务器,每台服务器上分别安装magent和memcached服务,并设为开机启动。这样做的好处是任何一台服务器宕机后都不影响magent pool获取memcache信息,即实现了memcached的高可用(HA),如果两台机器都宕机了,只能说明你RP太差了。当然,也可以用三台、四台或者更多服务器来提高HA。
二、安装memcached和Magent
1.安装memcached,请参考:http://blog.csdn.net/zhu_tianwei/article/details/44542497
2.安装Magent
1)下载安装
wget http://memagent.googlecode.com/files/magent-0.6.tar.gz
tar -zxvf magent-0.6.tar.gz
make
检查是否安装成功:
./magent -h
memcached agent v0.6 Build-Date: Mar 27 2015 07:09:30
错误修改
1)错误1
gcc -Wall -g -O2 -I/usr/local/include  -c -o magent.o magent.c
magent.c: In function ‘writev_list’:
magent.c:729: error: ‘SSIZE_MAX’ undeclared (first use in this function)
magent.c:729: error: (Each undeclared identifier is reported only once
magent.c:729: error: for each function it appears in.)
make: *** [magent.o] Error 1
处理,在ketama.h开头添加
#ifndef SSIZE_MAX
#define SSIZE_MAX      32767
#endif
2)错误2
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o ketama.o ketama.c
gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a
/usr/lib64/libevent.a(event.o): In function `gettime’:
(.text+0×449): undefined reference to `clock_gettime’
/usr/lib64/libevent.a(event.o): In function `event_base_new’:
(.text+0x72a): undefined reference to `clock_gettime’
collect2: ld returned 1 exit status
make: *** [magent] Error 1
处理:
vim Makefile
CFLAGS = -Wall -g -O2 -I/usr/local/include $(M64)
改为:    
CFLAGS = -lrt -Wall -g -O2 -I/usr/local/include $(M64)
3)错误3
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o magent.o magent.c
gcc -Wall -g -O2 -I/usr/local/include -m64 -c -o ketama.o ketama.c
gcc -Wall -g -O2 -I/usr/local/include -m64 -o magent magent.o ketama.o /usr/lib64/libevent.a /usr/lib64/libm.a
gcc: /usr/lib64/libm.a:没有那个文件或目录
make: *** [magent] 错误 1
解决办法
ln -s /usr/lib64/libm.so /usr/lib64/libm.a
注:有可能还会报错 gcc: /usr/lib64/libevent.a: 没有那个文件或目录
如果有,可执行
vi Makefile
找到 LIBS = /usr/lib64/libevent.a /usr/lib64/libm.a
修改 LIBS = /usr/libevent 的安装路径/libevent.a /usr/lib64/libm.a
例: LIBS = /usr/lib/libevent.a /usr/lib64/libm.a
三、启动服务
1.memcached
192.168.36.54:11211
192.168.36.189:11211
./memcached/bin/memcached -d -m 64 -p 11211
2.magent
192.168.36.54
 ./magent/magent -n 4096  -l 192.168.36.54 -p 11200 -s 192.168.36.54:11211 -b 192.168.36.189:11211
192.168.36.189 
./magent/magent -n 4096  -l 192.168.36.189 -p 11200 -s 192.168.36.189:11211 -b 192.168.36.54:11211
magent参数说明:
  -h 帮助说明
  -u 用户
  -g gid
  -p 启动端口, 默认11211. (0 to disable tcp support)
  -s 服务memcached地址,ip:port, set memcached server ip and port
  -b 备份memcached地址,ip:port, set backup memcached server ip and port
  -l 启动IP地址,ip, local bind ip address, default is 0.0.0.0
  -n 最大并发数number, set max connections, default is 4096
  -D 非后台运行don’t go to background
  -k use ketama key allocation algorithm
  -f file, unix socket path to listen on. default is off
  -i number, set max keep alive connections for one memcached server, default is 20
  -v verbose
四、测试
1.通过代理magent添加数据,查看服务和备份memcached
通过任何一个代理magent添加数据,2台memcached都存在。
2.关闭一个服务memcached,再重启查看数据是否存在
关闭192.168.36.189的memcached,通过192.168.36.189的magent可以查询数据,来自备份机器。
再启动,由于没有持久化,所有数据都无法查询,另外一台magent正常。再启动192.168.36.189的memcached的时候,可以从备份Memcached服务恢复数据,起到了容错的作用。
通过以上测试可以得出结论:
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模式下。

document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
    <div id="digg" articleid="44685691">        <dl id="btnDigg" class="digg digg_disable" onclick="btndigga();">             <dt>顶</dt>            <dd>0</dd>        </dl>        <dl id="btnBury" class="digg digg_disable" onclick="btnburya();">              <dt>踩</dt>            <dd>0</dd>                       </dl>    </div> <div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank">&nbsp;</a>   </div><div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank">&nbsp;</a></div><script type="text/javascript">            function btndigga() {                $(".tracking-ad[data-mod='popu_222'] a").click();            }            function btnburya() {                $(".tracking-ad[data-mod='popu_223'] a").click();            }        </script>


集群启动命令

一、启动Memcache(2台)
/usr/local/memcached/bin/memcached -d -m 4096 -u root -p 11213 -P /tmp/memcached-exams.pid

二、启动magent
/usr/local/magent/magent -u root -n 51200 -l 10.27.164.120 -p 12000 -s 10.27.164.120:11213 -s 10.46.24.161:11213