由于使用memcached时,memcached不提供集群功能,因为集群的要素是负载均衡和单点恢复;我的思路是用magent来实现负载均衡,利用repcached来实现单点恢复。使用magent+repcache的方式,最大程度利用服务器来存储不同的数据,和使用相同的资源;同时解决无法同步数据,容易造成单点故障等问题。
如何解决高并发下数据的查询效率,保证数据的高可用性和稳定性,在应用中显的越来越重要,本文采取的方式是memcached+magent+repache模式。
一、基本介绍
Repcached,全称replication cached,高可用技术,简称复制缓冲区技术。
使用场景:它是一个单Master单Slave的方案,但它的Master和Slave都是可读可写的,而且可以相互同步,并且Master和Slave会自动切换(主变从,从变主自由切换)。如果Master宕机,Slave侦测到连接断了,它会自动Listen而成为Master,而如果Slave坏掉,Master也会侦测到连接断了,它就会重新等待新的Slave加入。
二:准备条件
libevent-2.0.21-stable.tar.gz http://download.csdn.net/detail/qq_34021712/9763358
memcached-1.2.8-repcached-2.2.tar.gz(repcache完整版已经集成了memcached,不需要单独安装memcached) http://download.csdn.net/detail/qq_34021712/9763494
magent-0.5.tar.gz http://download.csdn.net/detail/qq_34021712/9763506
三:编译安装
1、编译安装libevent和magent在另一篇博客中已经说明了,可以参考http://blog.csdn.net/qq_34021712/article/details/55272599,只不过在装memcached的时候,不要安装普通的memcached,要安装和repcache集成的memcached,否则会报错说找不到 -x 和 -X 属性
现象:
[root@localhost ~]$ /usr/local/memcache/bin/memcached -p 11212 -x localhost -v -d
/usr/local/memcache/bin/memcached: invalid option -- x
Illegal argument "?"
[root@localhost ~]$
2、编译安装Memcached:
#cp memcached-1.2.8-repcached-2.2.1.tar.gz /usr/local
#cd /usr/local
#tar zxvf memcached-1.2.8-repcached-2.2.1.tar.gz
#mv memcached-1.2.8-repcached-2.2.1 memcached
#cd memcached
#./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/lib --enable-replication --enable-64bit
注意:默认memcached单个进程只支持到2G内存,需要更大内存支持的话,需要打开64位支持,编译的时候加参数:--enable-64bit
#make && make install
提示编译出错:
make all-recursive
make[1]: Entering directory `/usr/local/memcached'
Making all in doc
make[2]: Entering directory `/usr/local/memcached/doc'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/usr/local/memcached/doc'
make[2]: Entering directory `/usr/local/memcached'
gcc -DHAVE_CONFIG_H -I. -DNDEBUG -m64 -g -O2 -MT memcached-memcached.o -MD
MP -MF .deps/memcached-memcached.Tpo -c -o memcached-memcached.o `test -f
memcached.c' || echo './'`memcached.c
memcached.c: In function ‘add_iov’:
memcached.c:697: error: ‘IOV_MAX’ undeclared (first use in this function)
memcached.c:697: error: (Each undeclared identifier is reported only once
memcached.c:697: error: for each function it appears in.)
make[2]: *** [memcached-memcached.o] Error 1
make[2]: Leaving directory `/usr/local/memcached'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/usr/local/memcached'
make: *** [all] Error 2
解决方案:
vi memcached.c
将下面的几行
/* FreeBSD 4.x doesn't have IOV_MAX exposed. */
#ifndef IOV_MAX
#if defined(__FreeBSD__) || defined(__APPLE__)
# define IOV_MAX 1024
#endif
#endif
修改为
/* FreeBSD 4.x doesn't have IOV_MAX exposed. */
#ifndef IOV_MAX
# define IOV_MAX 1024
#endif
重新编译和安装:
#make && make install
查看帮助:
#./bin/memcached -h 可以看到memcached出现了 -x 和-X 属性
3、起一个magent,管理以上两个memcached,其中11221端口为主,11222端口为从:
四:方案设计
首先参考最简单的一主一从互为备份的情况,即如下图所示,M1做主即,M2做备份。
此时利用MA调度两个memcached,可以实现当M1宕机时,MA可以从M2中获取数据,对用户来说无影响。
缺点:1:M1宕机时可以从M2获取数据,但当M1恢复时,MA无法获取数据。虽然当有N个主机时,memcached数据丢失的量仅为1/N。但M1宕机时从M2获取数据效率不高。
2:M1重启时无法从M2中同步到数据。
根据上述第二个缺点引入Mrepcached,主要作用是将M1和M2绑定至同一同步接口,通过memcached重启恢复时,对数据进行同步解决数据丢失的问题。由于如果将多个(大于2个)memcached绑定在同一同步接口下时,会存在大量不必要的同步操作,我们选择1对1的方式进行主备设计:
缺点:1:逻辑上较为复杂,且当M1宕机时,M3会充当主机,原本分配给M2的key:value,可能分给了M3,而当M1恢复时,M3再宕时,虽然M1接管M3的数据,再次变为主机,但是它已经不是之前的M1了。对于MA管理者来说管理起来会很困难。
2:不易扩充扩展,当MEM数量较多时,无论是添加新的主备MEM。还是添加新的MA管理入口,都将会面临复杂的主从关系的判定(注)。
注:如果将两个MEM加入到同一同步接口以后,指定其中一个如M1为主M2为备时,如果M1宕机,这时M2会自动升级为主机。再当M1恢复时也只能从M2拉取数据,并不能抢占式的成为主机。所以当系统重新指定第二个(如南北两个访问节点时)MA2很难指定其中M1或M3谁是主谁是备份了。
针对上述确定,拟采用多MA负载分担实现N主N备方案:
首先,通过MA-USER到MA-1、MA-2这层实现负载分担,通过多MA-n来有效利用系统的硬件资源来快速响应数据访问的请求。其次通过MA-1到M1-S、M1-B这层来实现单点故障恢复。
具体来说,当M1-S宕机时,M1-B将自动成为主机,这样的话,当M1-S重启恢复时有两点好处。第一:对于MA-USER来说,MA-1/MA-2的逻辑顺序没有发生改变,这对于存在MA-MGR的系统是有好处的,因为MA-USER在分配key到MA-n上时使用的是简单的散列余数算法。第二:对于MA-1来说,由于MA-1在初始化的时候就已经指定主备关系了,使用过程中并不会修改MA-1的设置,所以无论MA-1中的主备关系如何倒换,都会屏蔽在MA-n层面,将不会影响后续相关的扩展和移植。
五:方案验证
启动M1-S, M1-B, M2-S, M2-B
#memcached -v -d -p 11221 -u root -P/tmp/memcached1.pid -x 127.0.0.1 -X 11111
#memcached -v -d -p 11222 -u root -P/tmp/memcached1.pid -x 127.0.0.1 -X 11111
#memcached -v -d -p 11321 -u root -P/tmp/memcached1.pid -x 127.0.0.1 -X 11112
#memcached -v -d -p 11322 -u root -P/tmp/memcached1.pid -x 127.0.0.1 -X 11112
启动MA-1、MA-2、MA-USER
#magent -u root -n 51200 -l 127.1 -p 11200-s 127.1:11221 -b 127.1:11222
#magent -u root -n 51200 -l 127.1 -p 11300-s 127.1:11321 -b 127.1:11322
#magent -u root -n 51200 -l 10.2.48.150 -p12000 -s 127.1:11200 -s 127.1:11300
注:其中没有启动备份MA,完整的应该是MA-1/MA-2/……/MA-n/MA-B
键入数据
取数据
数据在MA-1和MA-2中负载均衡。(也可telnet11200和11300)
kill进程M1-S,模拟单点故障。
单点故障时键入u5、u6数据,发现M1-B成功升级为M1-S并完成相应的MA-1的负载分担工作。再重新启动M1-S,模拟故障恢复。
可以看出M1-S成功启动并从M1-B中恢复所有数据。
六:扩展
由于时间和水平有限,本文仅讨论了基础的实现,在此基础上若添加MA-Bn的备份集群可实现N:2N的备份。另外在系统的垂直方向上也可以根据需要不断扩展加深,最终实现完全根据需要的1:N备份功能。
参考资料:
http://blog.csdn.net/lsh3958411/article/details/36865837
http://www.tuicool.com/articles/UzAr2i