1. 程式人生 > >生產環境實踐:redis高可用架設

生產環境實踐:redis高可用架設

rediskeepalived


經過測試,當主redis停掉的時候,可以5秒鐘內切換到從redis,反之切換到主,也是一樣的時間。

在A服務器(192.168.16.29),B服務器(192.168.16.2)上均安裝redis,keepalived

A作為默認的master,B作為slave(redis的配置文件中加上 SLAVEOF 192.168.16.29 6379)即可。

A,B上的Redis均開啟本地化策略,appendonly yes


Master 192.168.16.29

Slave 192.168.16.2

Vip 192.168.16.3

Master redis 端口:6379

Slave redis 端口:6379

技術分享圖片


安裝程序包:

#yum -y install gcc gcc+ gcc-c++ openssl openssl-devel pcre pcre-devel

安裝keepalived

Master 192.168.16.29部署

keepalived安裝部署就不做詳細說明了,在架構那塊會做詳細說明。

#wget http://www.keepalived.org/software/keepalived-1.2.23.tar.gz
#tar xf keepalived-1.2.23.tar.gz
#cd keepalived-1.2.23
#./configure --prefix=/usr/local/keepalived
#make && make install
#cp keepalived/etc/init.d/keepalived.sysconfig /etc/sysconfig/keepalived
#cp keepalived/etc/init.d/keepalived.rh.init /etc/init.d/keepalived
#chmod a+x /etc/init.d/keepalived
#ln -s /usr/local/keepalived/sbin/keepalived /sbin/keepalived
#chkconfig --add keepalived
#cp -a keepalived/etc/keepalived/ /etc/
#mkdir /usr/local/Script/ -p
#mkdir /usr/local/logs/ -p

keepalived配置

#vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
 
 
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id redis1.xxx.com
}
 
vrrp_script chk_redis {
script "/usr/local/Script/redis_check.sh"
interval 2
}
 
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 112
priority 101
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_redis
}
track_interface {
        eth0
}
virtual_ipaddress {
192.168.16.3 dev eth0
}
notify_master /usr/local/Script/redis_master.sh
notify_backup /usr/local/Script/redis_backup.sh
notify_fault /usr/local/Script/redis_fault.sh
notify_stop /usr/local/Script/redis_stop.sh
}

編寫以下負責運作的關鍵腳本:

notify_master /usr/local/Script/redis_master.sh
notify_backup /usr/local/Script/redis_backup.sh
notify_fault /usr/local/Script/redis_fault.sh
notify_stop /usr/local/Script/redis_stop.sh


因為keepalived在轉換狀態時會依照狀態來呼叫:

當進入Master狀態時會呼叫notify_master

Backup狀態時會呼叫notify_backup

當發現異常情況時進入Fault狀態呼叫notify_fault

keepalived程序終止時呼叫notify_stop

Slave 192.168.16.2 keepalived部署


從節點安裝方法一樣

#wget http://www.keepalived.org/software/keepalived-1.2.23.tar.gz
#tar xf keepalived-1.2.23.tar.gz
#cd keepalived-1.2.23
#./configure --prefix=/usr/local/keepalived
#make && make install
#cp keepalived/etc/init.d/keepalived.sysconfig /etc/sysconfig/keepalived
#cp keepalived/etc/init.d/keepalived.rh.init /etc/init.d/keepalived
#chmod a+x /etc/init.d/keepalived
#ln -s /usr/local/keepalived/sbin/keepalived /sbin/keepalived
#chkconfig --add keepalived
#cp -a keepalived/etc/keepalived/ /etc/
#mkdir /usr/local/Script/ -p 
#mkdir /usr/local/logs/ -p
 
 
keepalived配置
#vim /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
 
 
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id redis2.xxx.com
}
 
vrrp_script chk_redis {
script "/usr/local/Script/redis_check.sh"
interval 2
}
 
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 112
priority 99
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_redis       ##執行上面定義的chk_redis
}
track_interface {
        eth0
}
virtual_ipaddress {
192.168.16.3 dev eth0
}
notify_master /usr/local/Script/redis_master.sh
notify_backup /usr/local/Script/redis_backup.sh
notify_fault /usr/local/Script/redis_fault.sh
notify_stop /usr/local/Script/redis_stop.sh
}

Master 192.168.16.29 腳本編寫

##成為master


#vim  /usr/local/Script/redis_master.sh
#!/bin/bash
REDISCLI="/usr/local/redis/src/redis-cli"
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI -a 123456 SLAVEOF 192.168.16.2 6379 >> $LOGFILE 2>&1
sleep 5    ##延遲5秒以後待數據同步完成後再取消同步狀態
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI -p 6379 -a 123456 SLAVEOF NO ONE
$REDISCLI -p 6379 -a 123456 SLAVEOF NO ONE >> $LOGFILE 2>&1

#成為backup

#vim  /usr/local/Script/redis_backup.sh
#!/bin/bash
REDISCLI="/usr/local/redis/src/redis-cli"
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
sleep 5   #延遲5秒待數據被對方同步完成之後再切換主從角色
echo "Run SLAVEOF cmd..." >> $LOGFILE
$REDISCLI -a 123456 SLAVEOF 192.168.16.2 6379 >> $LOGFILE 2>&1
 
#監控腳本 exit 1 時
 
#vim  /usr/local/Script/redis_fault.sh
#!/bin/bash
 
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[fault]" >> $LOGFILE
date >> $LOGFILE
sh /usr/local/Script/redis_backup.sh
 
#keepalived 服務停止時
 
#vim  /usr/local/Script/redis_stop.sh
#!/bin/bash
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[stop]" >> $LOGFILE
date >> $LOGFILE
 
#監控腳本的路徑
 
#vim /usr/local/Script/redis_check.sh
#!/bin/bash
ALIVE=`/usr/local/redis/src/redis-cli -p 6379 -a 123456 PING`
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
if [ "$ALIVE" == "PONG" ]; then
echo $ALIVE
#echo "check master pong" >> $LOGFILE
exit 0
else
echo $ALIVE
exit 1
fi

給腳本授予權限

chmod a+x /usr/local/Script/*

Slave 192.168.16.2 腳本

#成為master
 
#vim /usr/local/Script/redis_master.sh
#!/bin/bash
REDISCLI="/usr/local/redis/src/redis-cli"
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1
echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI -p 6379 -a 123456  SLAVEOF NO ONE >> $LOGFILE 2>&1
 
#成為backup
 
#vim /usr/local/Script/redis_backup.sh
#!/bin/bash
REDISCLI="/usr/local/redis/src/redis-cli"
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
#sleep 10
echo "backup Run SLAVEOF 192.168.16.29 cmd..." >> $LOGFILE
$REDISCLI -a 123456 SLAVEOF 192.168.16.29 6379 >> $LOGFILE 2>&1
 
#監控腳本 exit 1 時 
 
#vim /usr/local/Script/redis_fault.sh
#!/bin/bash
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[fault]" >> $LOGFILE
date >> $LOGFILE
sh /usr/local/Script/redis_slave.sh
 
#keepalived 服務停止時
 
#vim /usr/local/Script/redis_stop.sh
#!/bin/bash
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[stop]" >> $LOGFILE
date >> $LOGFILE


#監控腳本的路徑

#vim /usr/local/Script/redis_check.sh
#!/bin/bash
ALIVE=`/usr/local/redis/src/redis-cli -a 123456 -h 192.168.16.29 -p 6379 PING`
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
if [ "$ALIVE" != "PONG" ]; then
echo $ALIVE
exit 0
else
echo $ALIVE
exit 1
fi

數據同步腳本

#vim /usr/local/Script/redis_slave.sh
#!/bin/bash
REDISCLI="/usr/local/redis/src/redis-cli"
LOGFILE="/usr/local/logs/keepalived-redis-state.log"
echo "[slave]" >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1
sleep 5
date >> $LOGFILE
echo "slave Run SLAVEOF 192.168.16.3 cmd..." >> $LOGFILE
$REDISCLI -a 123456 SLAVEOF 192.168.16.29 6379 >> $LOGFILE 2>&1  
 
給腳本授予權限
chmod a+x /usr/local/Script/*

192.168.16.29 redis部署

# wget http://download.redis.io/releases/redis-3.0.6.tar.gz
# tar xzf redis-3.0.6.tar.gz -C /usr/local/
# cd /usr/local
# mv redis-3.0.6 redis
# cd redis
# make
 
新建redis目錄
#mkdir /usr/local/redis/logs
#mkdir /usr/local/redis/etc
#mkdir /usr/local/redis/data
#mkdir /var/run/redis/ -p
 
redis配置 
#vim /usr/local/redis/etc/redis.conf
daemonize yes
pidfile /var/run/redis/redis.pid
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/usr/local/logs/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /usr/local/redis/data
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass 123456
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
 
redis啟動腳本
#!/bin/bash  
#description:simple example service  
RETVAL=0
REDIS_COMMOND=/usr/local/redis/src/redis-server
REDIS_CONFIG_FILE=/usr/local/redis/etc/redis.conf
REDIS_PID=/var/run/redis/redis.pid
REDIS_XINXI=`ps -ef | grep redis | grep -v grep |wc -l`
start(){
        $REDIS_COMMOND $REDIS_CONFIG_FILE
        if [ $REDIS_XINXI -gt 1 ];then
                echo "redis Start-up success!"
        else
                echo "redis Start-up failure!"
        fi
}
 
stop(){
        /bin/kill -s QUIT `cat $REDIS_PID`
        if [ $? -eq 0 ];then
                echo "redis Stop success!"
        fi
}
 
reload(){
        /bin/kill -s HUP `cat $REDIS_PID`
        REDIS_XINXI_RELOAD=`ps -ef | grep redis| grep -v grep |wc -l`
        if [ $REDIS_XINXI_RELOAD -gt 1 ];then
                echo "redis reload success!"
        else
                exit 0
        fi
}
 
case $1 in
start)
        start
;;
stop)
        stop
;;
reload)
        reload
;;
*)
echo "error choice ! please input start|stop|reload";;
esac
exit $RETVA

授予執行權限

#chmod a+x /etc/init.d/redisd

啟動redis 主服務器

#chmod a+x /etc/init.d/redisd

192.168.16.2 redis部署

# wget http://download.redis.io/releases/redis-3.0.6.tar.gz
# tar xzf redis-3.0.6.tar.gz -C /usr/local/
# cd /usr/local
# mv redis-3.0.6 redis
# cd redis
# make
 
新建redis目錄
#mkdir /usr/local/redis/logs
#mkdir /usr/local/redis/etc
#mkdir /usr/local/redis/data
#mkdir /var/run/redis/ -p
復制代碼
 
redis配置 
##vim /usr/local/redis/etc/redis.conf
daemonize yes
pidfile /var/run/redis/redis.pid
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile "/usr/local/logs/redis.log"
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /usr/local/redis/data/
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
masterauth 123456
requirepass 123456
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
slaveof 192.168.16.29 6379
 
redis啟動腳本
#!/bin/bash  
#description:simple example service  
RETVAL=0
REDIS_COMMOND=/usr/local/redis/src/redis-server
REDIS_CONFIG_FILE=/usr/local/redis/etc/redis.conf
REDIS_PID=/var/run/redis/redis.pid
REDIS_XINXI=`ps -ef | grep redis | grep -v grep |wc -l`
start(){
        $REDIS_COMMOND $REDIS_CONFIG_FILE
        if [ $REDIS_XINXI -gt 1 ];then
                echo "redis Start-up success!"
        else
                echo "redis Start-up failure!"
        fi
}
 
stop(){
        /bin/kill -s QUIT `cat $REDIS_PID`
        if [ $? -eq 0 ];then
                echo "redis Stop success!"
        fi
}
 
reload(){
        /bin/kill -s HUP `cat $REDIS_PID`
        REDIS_XINXI_RELOAD=`ps -ef | grep redis| grep -v grep |wc -l`
        if [ $REDIS_XINXI_RELOAD -gt 1 ];then
                echo "redis reload success!"
        else
                exit 0
        fi
}
 
case $1 in
start)
        start
;;
stop)
        stop
;;
reload)
        reload
;;
*)
echo "error choice ! please input start|stop|reload";;
esac
exit $RETVA
 
授予執行權限
#chmod a+x /etc/init.d/redisd
 
啟動redis 主服務器
#chmod a+x /etc/init.d/redisd

做好以上事情,接下來我們可以啟動keepalived

在Master 192.168.16.29啟動keepalived
#/etc/init.d/keepalived start
 
在Slave 192.168.16.2啟動keepalived 
#/etc/init.d/keepalived start

故障轉移測試

Master 192.168.16.29輸入ip a查看虛擬IP192.168.2.3

[root@localhost ~]# ip a
1: lo: mtu 65536 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: mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:84:40:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.16.29/24 brd 192.168.16.255 scope global eth0
    inet 192.168.16.3/32 scope global eth0
    inet6 fe80::20c:29ff:fe84:40c4/64 scope link 
       valid_lft forever preferred_lft forever
 
 
關閉redis主服務器(192.168.16.29)
[root@localhost keepalived-1.2.23]# /etc/init.d/redisd stop
redis Stop success!
[root@localhost keepalived-1.2.23]# ip a
1: lo: mtu 65536 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: mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:84:40:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.16.29/24 brd 192.168.16.255 scope global eth0
    inet6 fe80::20c:29ff:fe84:40c4/64 scope link 
       valid_lft forever preferred_lft forever
[root@localhost keepalived-1.2.23]#
 
keepalived檢測到redis異常,把主身份切換到從(192.168.16.2)
 
Redis Master 192.168.16.29日誌
[root@localhost ~]# tail -f /usr/local/logs/keepalived-redis-state.log 
[fault]
2016年 10月 19日 星期三 14:40:39 CST
[backup]
2016年 10月 19日 星期三 14:40:39 CST
Being slave....
Run SLAVEOF cmd...
Could not connect to Redis at 127.0.0.1:6379: Connection refused
 
Redis Slave 192.168.16.2日誌
[root@localhost Script]# tail -f /usr/local/logs/keepalived-redis-state.log
[backup]
2016年 10月 19日 星期三 14:43:24 CST
Being slave....
backup Run SLAVEOF 192.168.16.29 cmd...
OK Already connected to specified master
[master]
2016年 10月 19日 星期三 14:43:28 CST
Being master....
Run SLAVEOF NO ONE cmd ...
OK
 
可以看出Slave已經接管了Master角色
 
 
在Slave 192.168.16.2輸入ip a查看虛擬IP
[root@localhost keepalived-1.2.23]# ip a
1: lo: mtu 65536 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: mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:aa:43:58 brd ff:ff:ff:ff:ff:ff
    inet 192.168.16.2/24 brd 192.168.16.255 scope global eth1
    inet 192.168.16.3/32 scope global eth1
    inet6 fe80::20c:29ff:feaa:4358/64 scope link 
       valid_lft forever preferred_lft forever
 
 
在Master 192.168.16.29啟動redis,16.29已經恢復了Master的角色
 
[root@localhost ~]# /etc/init.d/redisd start
redis Start-up success!
[root@localhost ~]# ip a
1: lo: mtu 65536 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: mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:84:40:c4 brd ff:ff:ff:ff:ff:ff
    inet 192.168.16.29/24 brd 192.168.16.255 scope global eth0
    inet 192.168.16.3/32 scope global eth0
    inet6 fe80::20c:29ff:fe84:40c4/64 scope link 
       valid_lft forever preferred_lft forever


生產環境實踐:redis高可用架設