Memcached群集部署
一、Memcached群集概述
Memcached本身是基于内存的缓存,它的设计本身没用冗余机制。如果一个Memcached节点失去了所有的数据,理论上后端的应用程序可以从数据源中再次获取到数据。如果担心节点失效会大大加重数据库的负担,可以增加更多的节点来减少丢失一个节点的影响,热备节点在其他节点宕机的时候接管VIP。但是多台节点无法实现存储不同的数据,最大程度的使用相同的资源:无法同步数据,容易造成单点故障。
关于实现memcached缓存集群可以有多种方式,一种是使用Repcached(memcached同步补丁),Repcached优点主要是数据冗余,两台memcached都可以进行读写操作,缺点是只支持单对单,指支持1.2.x版本,所以受到的局限性很大。另外可以使用开源软件Magent实现Memcached群集。通过Magent缓存代理,防止单点现象,缓存代理也可以做备份,可以用keepalived软件实现高可用。
memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能,各个memcached不会互相通信以共享数据,这完全取决于客户端实现。由于memcached服务器与服务器之间没有任何通信,并且不进行任何数据复制备份,所以当任何服务器节点出现故障时,会出现单点故障,如果需要实现HA,则需要通过另外的方式来解决。
通过magent缓存代理,防止单点现象,缓存代理也可以做备份,通过客户端连接到缓存代理服务器,缓存代理服务器连接缓存服务器,缓存代理服务器可以连接多台memcached机器,可以将每台memcached机器进行数据同步,如果其中一台缓存服务器宕机,系统依然可以继续工作,数据不会丢失并且可以保证数据的完整性。但是如果缓存代理服务器故障,那么缓存代理服务器将无法继续提供服务,所以用keepalived软件实现高可用
memcached虽然能够通过分布式缓存,实现其中memcached宕掉不会丢失全部缓存数据,但部分数据还是难逃一劫。
我们可以利用magent代理memcached实现主从备份来保证缓存数据完好无损,而且magent还可以作为从继续使用,但大体工作原理如下:
1.magent每次写数据都会写到主memcached和从memcached上,并且向主从memcached写的算法一样;
2.当主memcached宕掉,magent会向从memcached中读取数据;
3.当主memcached恢复后,magent将重新向主memcached中读数据;此时由于主memcached刚恢复,其中并无数据,因此会导致部分数据无法读取,这也是magent的一大缺点。
针对magent的缺点有几种想法:
1.在生产环境中主memcached宕掉的可能性非常小,大部分时间都是工作的;而从memcached只是在主memcached宕掉后才使用,因此从memcached分配的空间不可能和主memcached一样,这样无疑是在浪费宝贵的内存空间。
2.既然从memcached分配空间较小,而随着存入的数据会越来越多,会导致缓存的数据不断被过期驱逐出内存,因此在主memcached宕掉后,只能暂时起到缓解数据库压力的作用。
3.主memcached宕掉后,不宜直接将其启动,还是在数据库压力比较小的时候再启动吧,就当预热缓存。
总结:我引入magent除了主从方面,还考虑到magent---magent实现memcached入口的负载均衡,也就是说读写请求按照一定的算法分配到两个magent入口上,既能达到高可用,还能起到负载均衡。
2.使用service iptables stop关掉,并且不能用iptables -L -vnx查看,因此使用此命令会将防火墙开启,虽然规则是清空的,但仍会记录连接跟踪表。
二、Memcached群集案例案例环境: 主机名 IP地址 软件包主缓存节点 Master 192.168.8.10 magent、memcached、 libevent、keepalived
备缓存节点Backup
192.168.8.20magent、memcached、 libevent、keepalived
Client
192.168.8.30telnet
实验前先关闭三台机器的防火墙及selinux
1、主、备缓存节点编译安装libevent [iyunv@master ~]# tar xf libevent-1.4.9-stable.tar.gz -C /usr/src/ [iyunv@master ~]# cd /usr/src/libevent-1.4.9-stable/ [iyunv@master libevent-1.4.9-stable]# ./configure --prefix=/usr && make && make install
备缓存节点与主相同
2、主、备缓存节点编译安装memcached [iyunv@master libevent-1.4.9-stable]# cd [iyunv@master ~]# tar xf memcached-1.2.6.tar.gz -C /usr/src/ [iyunv@master ~]# cd /usr/src/memcached-1.2.6/ [iyunv@master memcached-1.2.6]# ./configure --with-libevent=/usr/ && make && make install 备缓存节点与主相同
3、主、备缓存节点安装magent(这个软件一般要翻墙才能下载) [iyunv@master ~]# mkdir magent [iyunv@master ~]# tar xf magent-0.5.tar.gz -C magent/ [iyunv@master ~]# cd magent/ [iyunv@master magent]# ls ketama.c ketama.h magent.c Makefile [iyunv@master magent]# vim ketama.h
1 #ifndef SSIZE_MAX //手动添加此三行在文件开头处 2 #define SSIZE_MAX 32767 3 #endif ……
[iyunv@master magent]# ldconfig [iyunv@master magent]# sed -i '1 s/$/ -lm/' Makefile [iyunv@master magent]# head -1 Makefile LIBS = -levent -lm [iyunv@master magent]# make gcc -Wall -O2 -g -c -o magent.o magent.c gcc -Wall -O2 -g -c -o ketama.o ketama.c gcc -Wall -O2 -g -o magent magent.o ketama.o -levent -lm
[iyunv@master magent]# ls ketama.c ketama.h ketama.o magent magent.c magent.o Makefile [iyunv@master magent]# cp magent /usr/bin/ [iyunv@master magent]# scp magent 192.168.8.20:/usr/bin/
4、主、备缓存节点安装keepalived [iyunv@master ~]# yum -y install keepalived [iyunv@master ~]# cd /etc/keepalived/ [iyunv@master keepalived]# cp keepalived.conf keepalived.conf.origin [iyunv@master keepalived]# vim keepalived.conf ! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.8.1
smtp_connect_timeout 30
router_id WEB_HA1
}
vrrp_script magent {
script "/opt/magent.sh"
interval 2
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
magent
}
virtual_ipaddress {
192.168.8.60
}
}
|
从上安装Keepalived [iyunv@backup ~]# yum -y install keepalived [iyunv@backup ~]# cd /etc/keepalived/ [iyunv@backup keepalived]# mv keepalived.conf keepalived.conf.origin [iyunv@backup keepalived]# scp 192.168.2.11:/etc/keepalived/keepalived.conf ./
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id WEB_HA2
}
vrrp_script magent {
script "/opt/magent.sh"
interval 2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.8.60
}
}
| [iyunv@backup ~]# service keepalived start
正在启动 keepalived: [确定]
5、编写主、备缓存服务器的magent监测脚本 magent参数详解: -u 指定用户,以root用户运行 -n 最大的连接数,默认不指定的话是4096 -l (小写L),magent对外监听的IP地址 -p magent对外监听的端口 -s 设置memcached主缓存的IP地址和端口 -b 设置memcached备缓存的IP地址和端口
主: [iyunv@master ~]# vim /opt/magent.sh #!/bin/bash k=`ps -ef |grep keepalived |grep -v grep |wc -l` if [ $k -gt 0 ];then magent -u root -n 51200 -l 192.168.8.60 -p 12000 -s 192.168.8.10:11211 -b 192.168.8.20:11211
else
pkill -9 magent
fi
[iyunv@master ~]# chmod +x /opt/magent.sh [iyunv@master ~]# scp /opt/magent.sh 192.168.8.20:/opt/ 备: [iyunv@backup ~]# vim /opt/magent.sh #!/bin/bash k=`ip a |grep 192.168.8.60 |wc -l` if [ $k -gt 0 ];then magent -u root -n 51200 -l 192.168.8.60 -p 12000 -s 192.168.8.10:11211 -b 192.168.8.20:11211 else pkill -9 magent fi
6、脚本测试 主缓存节点启动keepalived,查看magent是否启动 [iyunv@master ~]# /etc/init.d/keepalived start 正在启动 keepalived: [确定] [iyunv@master ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:2d:ab:56 brd ff:ff:ff:ff:ff:ff
inet 173.16.16.10/16 brd 173.16.255.255 scope global eth1
inet6 fe80::20c:29ff:fe2d:ab56/64 scope link
valid_lft forever preferred_lft forever
3: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:2d:ab:4c brd ff:ff:ff:ff:ff:ff
inet 192.168.8.10/24 brd 192.168.8.255 scope global eth0
inet 192.168.8.60/32 scope global eth0
inet6 fe80::20c:29ff:fe2d:ab4c/64 scope link
valid_lft forever preferred_lft forever
[iyunv@master ~]# ps aux |grep magent root 7456 0.0 0.0 17360 448 ? Ss 09:44 0:00 magent -u root -n 51200 -l 192.168.8.60 -p 12000 -s 192.168.8.10:11211 -b 192.168.8.20:11211 root 7512 0.0 0.1 103248 872 pts/0 S+ 09:44 0:00 grep magent 虽然11211端口还没打开,但是不影响magent服务的启动
停掉主的keepalived,启动备的,查看magent是否启动 [iyunv@master ~]# /etc/init.d/keepalived stop 停止 keepalived: [确定] [iyunv@backup ~]# /etc/init.d/keepalived start 正在启动 keepalived: [确定] [iyunv@backup ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:30:a7:e4 brd ff:ff:ff:ff:ff:ff
inet 192.168.8.20/24 brd 192.168.8.255 scope global eth0
inet 192.168.8.60/32 scope global eth0
inet6 fe80::20c:29ff:fe30:a7e4/64 scope link
valid_lft forever preferred_lft forever
[iyunv@backup ~]# ps aux |grep magent root 7296 0.0 0.0 17360 448 ? Ss 09:49 0:00 magent -u root -n 51200 -l 192.168.8.60 -p 12000 -s 192.168.8.10:11211 -b 192.168.8.20:11211 root 7315 0.0 0.1 103248 868 pts/0 S+ 09:49 0:00 grep magent 启动主的keepalived,从的会自动关闭magent [iyunv@master ~]# /etc/init.d/keepalived start 正在启动 keepalived: [确定] [iyunv@backup ~]# ps aux |grep magent root 8934 0.0 0.1 103248 872 pts/0 S+ 09:56 0:00 grep magent
6、启动memcached服务 [iyunv@master ~]# memcached -d -m 1 -u root -l 192.168.8.10 -p 11211 [iyunv@master ~]# netstat -anpt |grep memcached tcp 0 0 192.168.8.10:11211 0.0.0.0:* LISTEN 9465/memcached [iyunv@backup ~]# memcached -d -m 1 -u root -l 192.168.8.20 -p 11211 [iyunv@backup ~]# netstat -anpt |grep 11211 tcp 0 0 192.168.8.20:11211 0.0.0.0:* LISTEN 9699/memcached
7、客户端测试 [iyunv@client ~]# yum -y install telnet [iyunv@client ~]# telnet 192.168.8.60 12000 //链接VIP,magent对外提供的端口 Trying 192.168.8.60... Connected to 192.168.8.60. Escape character is '^]'. set test 0 0 5 amber STORED quit Connection closed by foreign host. [iyunv@client ~]# telnet 192.168.8.60 12000 //查看刚刚插入的值 Trying 192.168.8.60... Connected to 192.168.8.60. Escape character is '^]'. get test VALUE test 0 5 amber END quit Connection closed by foreign host. [iyunv@client ~]# telnet 192.168.8.10 11211 //查看主节点是否能得到数据 Trying 192.168.8.10... Connected to 192.168.8.10. Escape character is '^]'. get test VALUE test 0 5 amber END quit Connection closed by foreign host. [iyunv@client ~]# telnet 192.168.8.20 11211 //查看备节点是否能得到数据 Trying 192.168.8.20... Connected to 192.168.8.20. Escape character is '^]'. get test VALUE test 0 5 amber END quit Connection closed by foreign host. 以上,说明主、备缓存节点都有了手动插入的值
关闭主节点上的memcached [iyunv@master ~]# pkill memcached [iyunv@master ~]# netstat -anpt |grep memcached [iyunv@master ~]# 客户端连接magent代理缓存的VIP,查看是否可以查询到数据 [iyunv@client ~]# telnet 192.168.8.60 12000 Trying 192.168.8.60... Connected to 192.168.8.60. Escape character is '^]'. get test VALUE test 0 5 amber END quit Connection closed by foreign host. 以上说明memcached单节点故障,缓存依然存在
注意:如果将故障的memcached节点修复后,缓存是不会再通过到已修复的节点上的,如果是magent指定的主节点故障,那么主节点的缓存数据会丢失,修复后不能立刻重启memcached服务,如果重启,客户端会去查询主节点的数据。并发高的网站会拖死数据库。因此,建议一般业务低峰期的时候再启动memcached主节点服务。然后通过magent再指定主缓存节点和备缓存节点。
以下为错误操作示例: [iyunv@master ~]# memcached -d -m 1 -u root -l 192.168.8.10 -p 11211 [iyunv@master ~]# netstat -anpt |grep memcached tcp 0 0 192.168.8.10:11211 0.0.0.0:* LISTEN 14064/memcached [iyunv@client ~]# telnet 192.168.8.60 12000 Trying 192.168.8.60... Connected to 192.168.8.60. Escape character is '^]'. get test END quit Connection closed by foreign host. 缓存数据已丢失
|