打造基于repcached+keepalived的高可用memcached集群

696 阅读8分钟

一 简介

Repcached是用来实现 Memcached 复制功能的一个工具。它所构建的主从方案是一个单主单从的方案,不支持多主多从。但是,它的特点是主从两个节点可以互相读写,从而达到互相同步的效果

注意事项:

  • 如果主节点坏掉,从节点会很快侦测到连接断开,然后它会自动切换到监听状态( listen)从而成为主节点,并且等待新的从节点加入
  • 如果原来挂掉的主节点恢复之后,我们只能人工手动以从节点的方式去启动。原来的主节点并不能抢占成为新的主节点,除非新的主节点挂掉。这也就意味着,基于 Repcached 实现的 Memcached 主从,针对主节点并不具备抢占功能

二 安装Repcached

(1)安装libevent:

下载地址:libevent.org/

[root@localhost ~]# cd /usr/local/src
[root@localhost src]# tar -zxvf libevent-2.1.8-stable.tar.gz
[root@localhost src]# cd libevent-2.1.8-stable
[root@localhost libevent-2.1.8-stable]# ./configure --prefix=/usr/local/
[root@localhost libevent-2.1.8-stable]# make && make install

查看是否安装成功:

[root@localhost libevent-2.1.8-stable]# ls -lh /usr/local/lib/libeven*

(2)安装memcached:

下载地址:memcached.org

[root@localhost ~]# cd /usr/local/src
[root@localhost src]# tar -zxvf memcached-1.5.4.tar.gz
[root@localhost src]# cd memcached-1.5.4
[root@localhost memcached-1.5.4]# ./configure --with-libevent=/usr
[root@localhost memcached-1.5.4]# make && make install

(3)安装repcached:

下载地址:sourceforge.net/projects/re…

[root@localhost ~]# cd /usr/local/src
[root@localhost src]# tar -zxvf memcached-1.2.8-repcached-2.2.1.tar.gz
[root@localhost src]# cd memcached-1.2.8-repcached-2.2.1
[root@localhost memcached-1.2.8-repcached-2.2.1]# ./configure --enable-replication --program-transform-name=s/memcached/repcached/
[root@localhost memcached-1.2.8-repcached-2.2.1]# make && make install

make的时候发现爆了以下错误:

解决方案是修改/usr/local/src/memcached-1.2.8-repcached-2.2.1/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即可

三 启动配置

[root@localhost init.d]# useradd memcached -s /bin/false
[root@localhost init.d]# mkdir -p /var/run/memcached

(1)启动master节点memcached:

[root@localhost init.d]# /usr/local/bin/repcached -d -p 11211 -u memcached -m 1024 -c 4096 -t 4 -P /var/run/memcached/memcached.pid -v >> /tmp/memcached.log 2>&1

如果出现memcached无法启动,并且查看日志文件(/tmp/memcached.log)发现以下错误:

则可以通过以下方式解决:

[root@localhost lib]# LD_DEBUG=libs /usr/local/bin/repcached -v

可以发现搜索的路径有/usr/lib64,因此在这个目录创建一个libevent-2.1.so.6的软链接即可:

[root@localhost lib]# ln -s /usr/local/lib/libevent-2.1.so.6 /usr/lib64/

再次启动,如果日志文件中出现以下提示则说明master节点已经启动成功了:

[root@localhost ~]# tail -f /tmp/memcached.log

(2)启动salve节点memcached:

[root@localhost init.d]# /usr/local/bin/repcached -d -x 192.168.1.159 -p 11211 -u memcached -m 1024 -c 4096 -t 4 -P /var/run/memcached/memcached.pid -v >> /tmp/memcached.log 2>&1

注:-x参数表示master节点地址

如果日志文件中出现以下提示则说明slave节点已经启动成功了:

[root@localhost ~]# tail -f /tmp/memcached.log

附:关于memcached启动命令的介绍:

  • -d:启动一个守护(daemon)进程
  • -m:分配给 memcache 使用的内存数量,单位是MB
  • -u:运行 memcache 的用户
  • -l:监听的服务器IP地址
  • -p:设置 memcache 监听的端口,端口最好大于1024
  • -c:设置 memcache 最大运行的并发连接数,默认是1024
  • -t:设置最大线程数
  • -v:输出日志,-vv -vvv也是输出日志,不过其详细程度依次递增
  • -P:设置保存 memcache 的pid文件地址。设置pid文件的好处在于方便结束memcache 进程,如果存在pid文件,那么我们就可以通过如下命令快速结束 memcached 进程:kill `cat /var/run/memcached/memcached.pid`

(3)测试master节点和slave节点数据是否同步:

注:关于memcached的基本命令可以参考:www.runoob.com/memcached/m…

i)在master节点(192.168.1.159)执行:

[root@localhost ~]# telnet 192.168.1.159 11211

Trying 192.168.1.159…
Connected to 192.168.1.159.
Escape character is ‘^]’.
set hello 0 0 5
world
STORED

注:这里的“set hello 0 0 5”表示设置键值对,其KEY为“hello”,存储时间为永久,VALUE的字节数为5(world的长度为5)

ii)在slave节点(192.168.1.166)执行:

获取master节点设置的参数“hello”,并设置新参数“ping”

[root@bogon lib]# telnet 192.168.1.166 11211

Trying 192.168.1.166…
Connected to 192.168.1.166.
Escape character is ‘^]’.
get hello
VALUE hello 0 5
world
END
set ping 0 0 4
pong
STORED

当然,这个新设置的参数在master节点上也是可以获取到的:

注意事项:

由于memcached的主/从没有抢占功能,因此如果主节点因为某种原因挂掉,再次恢复之后,只能作为现有主节点(也就是原来的从节点,在主节点挂掉的时候自动从从节点升级为主节点)的从节点启动,如:

/usr/local/bin/repcached -d -x 192.168.1.166 -p 11211 -u memcached -m 1024 -c 4096 -t 4 -P /var/run/memcached/memcached.pid -v >> /tmp/memcached.log 2>&1

四 安装keepalived 并设置监控

资源准备:

  • 两台主机:192.168.1.159、192.168.1.166
  • 待使用的虚IP(VIP):192.168.1.167

(1)在两台服务器上面分别安装keepalived,安装步骤如下:

[root@localhost ~]# cd /usr/local/src
[root@localhost src]# tar -zxvf keepalived-1.3.6.tar.gz
[root@localhost src]# cd keepalived-1.3.6
[root@localhost keepalived-1.3.6]# ./configure
[root@localhost keepalived-1.3.6]# make && make install
 
[root@localhost ~]# cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig
[root@localhost ~]# mkdir /etc/keepalived
[root@localhost ~]# cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
[root@localhost ~]# cp /usr/local/sbin/keepalived /usr/sbin

添加keepalived启动脚本:

[root@localhost ~]# vim /etc/init.d/keepalived

其内容如下:

#!/bin/sh
#
# Startup script for the Keepalived daemon
#
# processname: keepalived
# pidfile: /var/run/keepalived.pid
# config: /etc/keepalived/keepalived.conf
# chkconfig: - 21 79
# description: Start and stop Keepalived
 
# Source function library
. /etc/rc.d/init.d/functions
 
# Source configuration file (we set KEEPALIVED_OPTIONS there)
. /etc/sysconfig/keepalived
 
RETVAL=0
 
prog="keepalived"
 
start() {
    echo -n $"Starting $prog: "
    daemon keepalived ${KEEPALIVED_OPTIONS}
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
}
 
stop() {
    echo -n $"Stopping $prog: "
    killproc keepalived
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
}
 
reload() {
    echo -n $"Reloading $prog: "
    killproc keepalived -1
    RETVAL=$?
    echo
}
 
# See how we were called.
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    reload)
        reload
        ;;
    restart)
        stop
        start
        ;;
    condrestart)
        if [ -f /var/lock/subsys/$prog ]; then
            stop
            start
        fi
        ;;
    status)
        status keepalived
        ;;
    *)
        echo "Usage: $0 {start|stop|reload|restart|condrestart|status}"
        exit 1
esac
 
exit $RETVAL

[root@localhost ~]# chmod a+x /etc/init.d/keepalived
[root@localhost ~]# chkconfig keepalived on

注意事项:

  • keepalived默认配置文件路径:/etc/keepalived/keepalived.conf
  • keepalived默认日志文件路径:/var/log/messages

(2)修改/etc/keepalived/keepalived.conf配置文件:

[root@localhost ~]# vim /etc/keepalived/keepalived.conf

主机192.168.1.159的配置文件修改之后内容如下:

! 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 LVS_DEVEL
   vrrp_skip_check_adv_addr
   vrrp_strict
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}
 
vrrp_instance VI_1 {
    state BACKUP      #两台配置此处均是BACKUP
    interface eth0       #IP所在网卡,注意不能写错,通过ifconfig查看
    virtual_router_id 52
    priority 100      #优先级,另一台改为80
    advert_int 1
    nopreempt          #不抢占,只在优先级高的机器上设置即可,优先级低的机器不设置
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.167
    }
}
 
virtual_server 192.168.1.167 11211 { 
    delay_loop 6 
    lb_algo rr 
    lb_kind DR 
    persistence_timeout 50 
    protocol TCP 
 
    real_server 192.168.1.159 11211 { 
        weight 3
        notify_down /etc/keepalived/kill_keepalived.sh
        TCP_CHECK { 
            connect_timeout 10 
            nb_get_retry 3 
            delay_before_retry 3 
            connect_port 11211
        } 
    } 
}

主机192.168.1.166的配置文件修改之后内容如下:

! 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 LVS_DEVEL
}
 
vrrp_instance VI_1 {
    state BACKUP      #两台配置此处均是BACKUP
    interface eth0
    virtual_router_id 52
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
       192.168.1.167
    }
}
 
virtual_server 192.168.1.167 11211 { 
    delay_loop 6 
    lb_algo rr 
    lb_kind DR 
    persistence_timeout 50 
    protocol TCP 
 
    real_server 192.168.1.166 11211 { 
        weight 3
        notify_down /etc/keepalived/kill_keepalived.sh
        TCP_CHECK { 
            connect_timeout 10 
            nb_get_retry 3 
            delay_before_retry 3 
            connect_port 11211
        } 
    } 
}

编写kill_keepalived.sh脚本:

[root@localhost keepalived]# vim /etc/keepalived/kill_keepalived.sh

内容如下:

#!/bin/bash 
 
pkill keepalived

注:目的很简单,当keepalived检测到mysql服务挂了之后触发这个脚本,杀死keepalived进程,让另一台机器接管

[root@localhost keepalived]# chmod a+x /etc/keepalived/kill_keepalived.sh

(3)测试:

分别启动192.168.1.159和192.168.1.166服务器的keepalived:

[root@localhost ~]# service keepalived start

可以发现虚IP(192.168.1.167)已经在其中一台服务器上面生成了。因此客户端连接memcached只需要连接192.168.1.167:11211即可

注意事项:

如果服务器启用了iptables,那么在虚IP生成的时候可能会自动生成一条禁止任何IP访问的规则,因此需要将该规则删掉

i)查看每条规则的行号:

[root@localhost ~]# iptables -L -n --line-number

ii)删除有关虚IP(192.168.1.167)的规则:

[root@localhost ~]# iptables -D INPUT 1

注:这里的“1”表示上面查到的行号

iii)保存防火墙规则:

[root@localhost ~]# service iptables save

参考: