一、基本介绍
1、组件承担的角色
1)memcache负责缓存对象。
2)repcached负责单主单从的同步备份。
3)magent代理实现N主N备。
4)monit监听以上组件的各个实例端口,保证故障自动重启。
2、集群思路
1)利用repcached对memcache进行1对1的主备设计
2)利用magent多MA负载分担实现N主N备方案。
3)利用monit的监听机制,实例宕机后,能够快速重启。
二、Monit安装及基本使用
1、下载安装
我用的是Centos 6.5,官网上发布了rpm包,直接下载安装即可
wget http://pkgs.repoforge.org/monit/monit-5.5-1.el6.rf.x86_64.rpm
rpm -ivh monit-5.5-1.el6.rf.x86_64.rpm
安装完成后,会在/etc目录下生成monit.conf文件和monit.d文件夹
2、启动
启动命令:/etc/init.d/monit start
默认监听端口为2812,启动成功后,可看到以下界面,说明安装成功
注意两点修改:
1)/etc/monit.conf文件中,要修改使用的IP地址,如例子为192.168.0.106,允许访问的地址设置为局域网内可访问,如192.168.0.1/24。若不先设置,默认启动的话,只能是本机浏览器访问才行,别的机器都不行。
set httpd port 2812 and
use address 192.168.0.106 # only accept connection from localhost
allow 192.168.0.1/24 # allow localhost to connect to the server and
allow admin:monit # require user 'admin' with password 'monit'
allow @monit # allow users of group 'monit' to connect (rw)
allow @users readonly # allow users of group 'users' to connect readonly
2)因为做实验的机器是安装在虚拟机Linux机器上的,本地为Windows,若还是无法访问,请尝试关闭Linux的防火墙:
#service iptables status 查看防火墙状态
#service iptables stop 关闭防火墙
3、配置文件修改
Monit是比较通用的监听组件,用得比较广泛,这里就针对目前要使用的Memcache相关组件进行监听配置的讲解(monit.conf里面已经有许多示例可以参照的)。
我们来看一个监控Apache的示例
#
# 监控apache
#
check process apache with pidfile /var/run/apache2.pid
start program = "/etc/init.d/apache2 start"
stop program = "/etc/init.d/apache2 stop"
# apache吃cpu和内存比较厉害,额外添加一些关于这方面的监控设置
if cpu > 50% for 2 cycles then alert
if cpu > 70% for 5 cycles then restart
if totalmem > 1500 MB for 10 cycles then restart
if children > 250 then restart
if loadavg(5min) greater than 10 for 20 cycles then stop
if failed host www.example.com port 8080 protocol http then restart
if 3 restarts within 5 cycles then timeout
group server
# 可选,依赖于nginx
depends on nginx
可以看出有以下几个关键点:
1、process 后面的是监控的进程名
2、start program和stop program是启动和停止的命令,注意这个命令不能是sh文件。
3、CPU占用率的监控写法还是比较简单的。
4、 if failed这一行写的是监听的IP和端口,这点很重要。
5、其他的语法,根据需要照着抄就OK。
所以说,Monit的监控进行的语法配置可以快速上手的,不过要精通就要另外下一番功夫了。
4、memcache进程监控写法
将memcache注册成服务,主要是方便start program和stop program两行命令方便书写。
check process memcache11211 with pidfile /tmp/memcached11211.pid
start program = "/usr/local/bin/memcached -d -m 64 -u root -l 192.168.0.106 -p 11211 -P /tmp/memcached11211.pid" with timeout 60 seconds
stop program = "/usr/bin/kill `cat /tmp/memcached11211.pid`"
if failed host 192.168.0.106 port 11211 then restart
if cpu is greater than 40% for 2 cycles then alert
if cpu > 60% for 5 cycles then restart
if 10 restarts within 10 cycles then timeout
启动命令是能够正常使用的,我们在命令行操作中使用杀进程的方式人为的停止memcache服务,过一段时间后,发现monit能够让该memcache重新启动。不过好像stop program起不到效果,在页面上点击stop service无法停止memcache服务。
有个办法是使用安装版的memcache,将这个启动文件进行裁剪,只剩下stop方法,如下:
#!/bin/sh
#
# memcached: MemCached Daemon
#
# chkconfig: - 90 25
# description: MemCached Daemon
#
# Source function library.
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
#[ ${NETWORKING} = "no" ] && exit 0
#[ -r /etc/sysconfig/dund ] || exit 0
#. /etc/sysconfig/dund
#[ -z "$DUNDARGS" ] && exit 0
stop()
{
echo -n $"Shutting down memcached: "
kill -9 `cat tmp/memcached11211.pid`
echo
}
# See how we were called.
case "$1" in
stop)
stop
;;
*)
echo $"Usage: $0 {stop}"
exit 1
esac
exit 0
其实就是将kill命令写进这个脚本文件里,然后将该文件保存在/etc/init.d/目录下,命名为stopmemcached11211。
这样,就可以在monit里配置/sbin/service stopmemcached11211 stop命令了。
因为这个脚本文件里,pid文件的名字是写死的,如果涉及多个memcache实例,只能copy多个这样的文件,然后再改一下文件名,本来想把这个命令做成参数化的,奈何对脚本文件编写不是很专业,临时写了个案例凑数,若有精通此项技能的同学,或是有别的好方法,还望多多指点,将这个改进一下。
repcached和magent也可以使用类似的操作。
另外,Monit本身是实用性非常强的组件之一,关于其通用的配置,各位很容易找到,在这里就不班门弄斧了。
5、注意几点
1)monit的start program和stop program要写完整路径,如/sbin/service等。
2)新增的注册服务,若出现Permission denied错误时,增加执行权限就可以了:chmod +x stopmemcached11211。
3)使用monit监控repcached进程时,由于主备切换的关系,在monit里的启动命令要写成Slave类型的,并且在启动Monit前,要先启动相关的repcached进程。
三、集群架构图
结构示意图注释:
1)M1-S为memcache工作节点,M1-B为memcache备份节点,两节点之间使用repcached复制。
2)MA-1,MA-2,MA-N表示多个magent代理节点,处于中间层,用户不可见。
3)MA-USER,MA-MGR为用户可见的代理节点
4)MA-1,M1-S,M1-B三个节点表示一个单主单备的模型,多个这样的单主单备模型组成一套N主N备方案。
这样,无论M1-S,M2-S的节点如何宕机,都不会有单点故障,也不会导致memcache节点顺序变化。
问:如果MA-1宕机,会不会导致单点故障?或是MA-USER宕机,情形又如何呢?
答:应该不会,magent代理节点是无状态的,只要memcache有数据,都应该没问题。另外MA-MGR为MA-USER的备份节点,只要MA-MGR和MA-USER不要同时宕机,一般都没问题。
四、实战演练
1、整体方案描述
6个memcache节点,使用repcached,其中4个做工作节点,2个做备份节点
3个magent节点(作为第二层),2个做工作节点,1个做备份节点
2个用户工作节点,MA-USER为工作节点,MA-MGR为备份节点
2、端口分配(拟定,各位可根据实际情况任意指定)
由于占用端口数量较多,使用表格整理方便查看。
名称 | 端口号 | 监听复制端口号 | 备注 |
memcached节点1 | 12211 | 15001 | 工作节点 |
memcached节点2 | 12212 | 15001 | 工作节点 |
memcached节点3 | 12311 | 15002 | 工作节点 |
memcached节点4 | 12312 | 15002 | 工作节点 |
memcached节点5 | 12411 | 15003 | 备份节点 |
memcached节点6 | 12412 | 15003 | 备份节点 |
magent节点1 | 13211 | - | 第二层,对内可见,对外不可见 |
magent节点2 | 13212 | - | 第二层,对内可见,对外不可见 |
magent节点3 | 13213 | - | 第二层,对内可见,对外不可见 |
magent节点4 | 14211 | - | 对外访问层 |
magent节点5 | 14212 | - | 备份节点 |
3、启动命令
1)新建memcache repcached节点
memcached -p 12211 -X 15001 -l 192.168.0.106 -v -d -u root
memcached -p 12212 -X 15001 -x 192.168.0.106 -v -d -u root
memcached -p 12311 -X 15002 -l 192.168.0.106 -v -d -u root
memcached -p 12312 -X 15002 -x 192.168.0.106 -v -d -u root
memcached -p 12411 -X 15003 -l 192.168.0.106 -v -d -u root
memcached -p 12412 -X 15003 -x 192.168.0.106 -v -d -u root
将这6条语句放在startRepcached.sh 文件中
2)新建magent节点(第二层magent)
magent -u root -n 2048 -l 192.168.0.106 -p 13211 -s 192.168.0.106:12211 -b 192.168.0.106:12212
magent -u root -n 2048 -l 192.168.0.106 -p 13212 -s 192.168.0.106:12311 -b 192.168.0.106:12312
magent -u root -n 2048 -l 192.168.0.106 -p 13213 -s 192.168.0.106:12411 -b 192.168.0.106:12412
将这3条语句放在startSecondMagent.sh 文件中
2)新建magent节点(第二层magent)
magent -u root -n 2048 -l 192.168.0.106 -p 14211 -s 192.168.0.106:13211 -b 192.168.0.106:13213
magent -u root -n 2048 -l 192.168.0.106 -p 14212 -s 192.168.0.106:13212 -b 192.168.0.106:13213
将这3条语句放在startMagent.sh 文件中
PS:用做测试机时,我只用了一台Linux机器,各位可根据实际机器IP配置,修改相应的命令即
我们使用PHP连接多台memcached服务器,做分布式缓存,实现如下:
$memcache = new Memcache; $memcache->addServer('192.168.252.134', 11211); $memcache->addServer('192.168.252.134', 11212); $memcache->addServer('192.168.252.134', 11213); for ($i = 0; $i < 1000; $i++) { $memcache->set($i, $i, 0, 1000); }
这样的实现是最直接、简单的,PHP应用直接连接memcached服务器。但也存在一个问题,就是可用性的问题,如果,有一台memcached 服务器宕机了,那么该服务器上的数据就丢失了,可能有人会认为,memcached本来就是做缓存的,缓存丢失就丢了呗,没什么大惊小怪的。其实不然滴, 缓存的命中率也是影响系统稳定性和高可用的一个指标嘛,难道每次丢了缓存,我们就那么心宽的“去数据库找数据就好咯”,这样缓存还有意义吗。
针对上面的问题,可以使用magent缓存代理服务器来管理memcached服务器,PHP应用由直接和多台memcached交互转变成和magent交互。那么,magent都帮我们做了什么呢?
我们先上个图看看
可以看出,magent作为memcached集群的代理,还可以做备份(192.168.252.134:11213为备份服务器),主缓存服务 器(192.168.252.134:11211、192.168.252.134:11212)宕机后,应用依旧可以用从备份服务器上读取到缓存。
magent依赖libevent库
magent依赖libevent库
magent依赖libevent库
重要的话说三遍!!
1)编译安装magent
cd /home mkdir ./magent cd ./magent wget -c https://memagent.googlecode.com/files/magent-0.5.tar.gz // 谷歌被墙了,如有需要可以评论留邮箱 tar xzvf ./magent-0.5.tar.gz /sbin/ldconfig sed -i "s#LIBS = -levent#LIBS = -levent -lm#g" Makefile make cp ./magent /usr/bin/magent
编译过程会遇到很多问题,参照这网址自行解决
2)memcached的搭建略过
3)启动memcached和magent
magent -u root -l 192.168.252.134 -p 11210 -s 192.168.252.134:11211 -s 192.168.252.134:11212 -b 192.168.252.134:11213
4)运行测试脚本
php $host = '192.168.252.134'; $port = '11210'; $mem = memcache_connect($host, $port); $key1 = 'mctest1'; $value1 = '1'; $mem->add($key1, $value1); $key2 = 'mctest2'; $value2 = '2'; $mem->add($key2, $value2); $key3 = 'mctest3'; $value3 = '3'; $mem->add($key3, $value3); $key4 = 'mctest4'; $value4 = '4'; $mem->add($key4, $value4); $key5 = 'mctest5'; $value5 = '5'; $mem->add($key5, $value5); $key6 = 'mctest6'; $value6 = '6'; $mem->add($key6, $value6);
服务器192.168.252.134:11211
服务器192.168.252.134:11212
服务器192.168.252.134:11213
主服务器上的数据都会备份到备份服务器上,如果主服务器宕机了,应用依旧可以从备份服务器上取数据。
更多的部署图
转自 原创文章,转载请注明:JC&hcoding.com
转自 https://blog.csdn.net/dailywater/article/details/50967278