redis + keepalived 雙主模型

redis + keepalived 雙主模型

架構圖:

redis11.png  

1.vip默認綁定在redis主上,由redis主提供服務,redis從為備用節點。(實際上提供服務的只是vip)
2.當redis主掛掉,vip會默認漂移至redis從。由redis從提供服務,redis主已經掛掉。
3.當redis主已經恢復,redis從繼續提供服務和掛載vip.
4.當redis從掛掉,vip會漂移到redis主上。當你修復好redis從,默認他會同步數據,然后變成備用節點。
5.只要redis主從不全掛,基本上是不會影響的。從而實現了雙主的模型。(此雙主并不是同時寫數據,只是邏輯上的雙主)

操作系統:centos 6.6 64bit

keepalived + redis主 : 192.168.155.205

keepalived + redis從 : 192.168.155.206

vip:192.168.155.207

1.兩臺redis環境準備工作(兩臺都做)

[root@web01 ~]# yum install vim gcc telnet wget lrzsz openssl openssl-devel openssl-clients ntpdate -y
[root@web01 ~]# sed -i 's@SELINUX=enforcing@SELINUX=disabled@g' /etc/sysconfig/selinux
[root@web01 ~]# setenforce 0
[root@web01 ~]# /etc/init.d/iptables stop
[root@web01 ~]# chkconfig iptables off
[root@web01 ~]# ntpdate time.nist.gov
分別修改主機名為redis_master 和 redis_slave
[root@web01 ~]# vim /etc/sysconfig/network
HOSTNAME=redis_master
[root@web02 ~]# vim /etc/sysconfig/network
HOSTNAME=redis_slave

兩臺機器分別重啟(不重啟機器也可以,使用hostname修改主機名,然后使用bash命令.)

2.兩臺機器分別安裝redis(兩臺都做)

[root@redis_master ~]# wget http://download.redis.io/releases/redis-3.2.0.tar.gz
[root@redis_master ~]# tar xf redis-3.2.0.tar.gz
[root@redis_master ~]# mkdir -p /usr/local/redis
[root@redis_master ~]# mv redis-3.2.0/*  /usr/local/redis
[root@redis_master redis]# cd /usr/local/redis
[root@redis_master redis]# make
[root@redis_master src]# cd src && make install
[root@redis_master src]# cd /usr/local/redis
[root@redis_master redis]# cp redis.conf   /etc/
[root@redis_master redis]# mkdir  -p  /redis/log      #日志目錄
[root@redis_master redis]# mkdir  -p   /redis/run     #pid文件目錄
[root@redis_master redis]# mkdir  -p   /redis/data    #本地快照數據庫存放目錄
[root@redis_master redis]# vi /etc/redis.conf         #編輯
daemonize yes  #設置后臺啟動redis
[root@redis_master redis]# sysctl vm.overcommit_memory=1
[root@redis_master redis]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@redis_master redis]# vi /etc/sysctl.conf        #編輯,在最后一行添加下面代碼
vm.overcommit_memory = 1
[root@redis_master redis]# sysctl -p #使設置立即生效

3.設置redis開機自動啟動

vi /etc/init.d/redis   #編輯,添加以下代碼
#!/bin/sh
# chkconfig:   2345 90 10
# description:  Redis is a persistent key-value database
# redis    Startup script for redis processe
# processname: redis
redis_path="/usr/local/bin/redis-server"
redis_conf="/etc/redis.conf"
redis_pid="/redis/run/redis.pid"
# Source function library.
. /etc/rc.d/init.d/functions
[ -x $redis_path ] || exit 0
RETVAL=0
prog="redis"
# Start daemons.
start() {
if [ -e $redis_pid -a ! -z $redis_pid ];then
echo $prog" already running...."
exit 1
fi
echo -n $"Starting $prog "
# Single instance for all caches
$redis_path $redis_conf
RETVAL=$?
[ $RETVAL -eq 0 ] && {
touch /var/lock/subsys/$prog
success $"$prog"
}
echo
return $RETVAL
}
# Stop daemons.
stop() {
echo -n $"Stopping $prog "
killproc -d 10 $redis_path
echo
[ $RETVAL = 0 ] && rm -f $redis_pid /var/lock/subsys/$prog
RETVAL=$?
return $RETVAL
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $prog
RETVAL=$?
;;
restart)
stop
start
;;
condrestart)
if test "x`pidof redis`" != x; then
stop
start
fi
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart}"
exit 1
esac
exit $RETVAL
[root@redis_master redis]# chmod 755 /etc/init.d/redis        #添加腳本執行權限
[root@redis_master redis]# chkconfig --add redis              #添加開啟啟動
[root@redis_master  redis]# chkconfig --level 2345 redis on  #設置啟動級別
[root@redis_master redis]# chkconfig --list redis             #查看啟動級別
[root@redis_master redis]# service redis restart              #重新啟動redis
Stopping redis                                             [  OK  ]
Starting redis                                             [  OK  ]

4.redis主從配置文件

redis_master配置文件

[root@redis_master redis]# vim /etc/redis.conf
protected-mode no    #必須要加的參數,在3.2版本
daemonize yes
pidfile /redis/run/redis.pid
port 6379
tcp-backlog 511
timeout 1800
tcp-keepalive 0
loglevel verbose
logfile "/redis/log/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 ./
slaveof 192.168.155.206 6379
slave-read-only yes
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
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_slave配置文件

[root@redis_slave  redis]# vim /etc/redis.conf
protected-mode no    #必須要加的參數,在3.2版本
daemonize yes
pidfile /redis/run/redis.pid
port 6379
tcp-backlog 511
timeout 1800
tcp-keepalive 0
loglevel verbose
logfile "/redis/log/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 ./
slaveof 192.168.155.205 6379
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
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,現在redis都配置了雙主,但是他們現在都不可以寫入,必須要配置keepalived,有redis主,才可以寫入。

小提示:經過最后面的測試,redis.conf配置文件,可以省略2個配置文件不寫,也可以測試成功,配置如下:

slaveof 192.168.155.206 6379
slave-read-only yes

5.redis配置文件詳解

daemonize yes                      
#以后臺daemon方式運行redis
pidfile "/var/run/redis.pid"       
#redis以后臺運行,默認pid文件路徑/var/run/redis.pid
port 6379                          
#默認端口
bind 127.0.0.1                      
#默認綁定本機所有ip地址,為了安全,可以只監聽內網ip
timeout 300                         
#客戶端空閑n秒后斷開連接,單位為秒;默認是 0 表示不斷開
loglevel verbose                   
#設置日志級別,支持四個級別:debug、notice、verbose、warning
logfile stdout                      
#日志記錄方式,默認為標準輸出,logs不寫文件,輸出到空設備/deb/null   
logfile "/redis/log/redis.log"      
#可以指定日志文件路徑
databases 16                        
#開啟數據庫的數量
save 900 1
save 300 10
save 60 10000  
創建本地數據庫快照,格式:save * *
900秒內,執行1次寫操作
300秒內,執行10次寫操作
60秒內,執行10000次寫操作

rdbcompression yes                  
#啟用數據庫lzf壓縮,也可以設置為no
dbfilename dump.rdb                 
#本地快照數據庫名稱
dir "/redis/6369/"                  
#本地快照數據庫存放目錄
requirepass 123456                  
#設置redis數據庫連接密碼
maxclients 10000                    
#同一時間最大客戶端連接數,0為無限制
maxmemory 1024MB                    
#設定redis最大使用內存,值要小于物理內存,必須設置
appendonly yes                      
#開啟日志記錄,相當于MySQL的binlog
appendfilename "appendonly.aof"     
#日志文件名,注意:不是目錄路徑

appendfsync everysec                
#每秒執行同步,還有兩個參數always、no一般設置為everysec,相當于MySQL事物日志的寫方式
slave-serve-stale-data yes          
#當主master服務器掛機或主從復制在進行時,是否依然可以允許客戶訪問可能過期的數據。
#在"yes"情況下,slave繼續向客戶端提供只讀服務,有可能此時的數據已經過期;
#在"no"情況下,任何向此server發送的數據請求服務(包括客戶端和此server的slave)都將被告知"error"
slave-read-only yes                 
#slave是否為"只讀",強烈建議為"yes"
repl-ping-slave-period 10           
#slave向指定的master發送ping消息的時間間隔(秒),默認為10
repl-timeout 60                     
#slave與master通訊中,最大空閑時間,默認60秒.超時將導致連接關閉 
repl-disable-tcp-nodelay no         
#slave與master的連接,是否禁用TCP nodelay選項。"yes"表示禁用
#那么socket通訊中數據將會以packet方式發送(packet大小受到socket buffer限制)。
1. Redis默認不是以守護進程的方式運行,可以通過該配置項修改,使用yes啟用守護進程
    daemonize no
2. 當Redis以守護進程方式運行時,Redis默認會把pid寫入/var/run/redis.pid文件,可以通過pidfile指定
    pidfile /var/run/redis.pid
3. 指定Redis監聽端口,默認端口為6379,作者在自己的一篇博文中解釋了為什么選用6379作為默認端口,
    因為6379在手機按鍵上MERZ對應的號碼,而MERZ取自意大利歌女Alessia Merz的名字
    port 6379
4. 綁定的主機地址
    bind 127.0.0.1
5.當 客戶端閑置多長時間后關閉連接,如果指定為0,表示關閉該功能
    timeout 300
6. 指定日志記錄級別,Redis總共支持四個級別:debug、verbose、notice、warning,默認為verbose
    loglevel verbose
7. 日志記錄方式,默認為標準輸出,如果配置Redis為守護進程方式運行,
    而這里又配置為日志記錄方式為標準輸出,則日志將會發送給/dev/null
    logfile stdout
8. 設置數據庫的數量,默認數據庫為0,可以使用SELECT <dbid>命令在連接上指定數據庫id
    databases 16
9. 指定在多長時間內,有多少次更新操作,就將數據同步到數據文件,可以多個條件配合
    save <seconds> <changes>
    Redis默認配置文件中提供了三個條件:
    save 900 1
    save 300 10
    save 60 10000
    分別表示900秒(15分鐘)內有1個更改,300秒(5分鐘)內有10個更改以及60秒內有10000個更改。
 
10. 指定存儲至本地數據庫時是否壓縮數據,默認為yes,Redis采用LZF壓縮,如果為了節省CPU時間,
    可以關閉該選項,但會導致數據庫文件變的巨大
    rdbcompression yes
11. 指定本地數據庫文件名,默認值為dump.rdb
    dbfilename dump.rdb
12. 指定本地數據庫存放目錄
    dir ./
13. 設置當本機為slav服務時,設置master服務的IP地址及端口,在Redis啟動時,
    它會自動從master進行數據同步
    slaveof <masterip> <masterport>
14. 當master服務設置了密碼保護時,slav服務連接master的密碼
    masterauth <master-password>
15. 設置Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis時需要通過AUTH <password>命令提供密碼,默認關閉
    requirepass foobared
16. 設置同一時間最大客戶端連接數,默認無限制,Redis可以同時打開的客戶端連接數為Redis進程可以打開的最大文件描述符數,
    如果設置 maxclients 0,表示不作限制。當客戶端連接數到達限制時,
    Redis會關閉新的連接并向客戶端返回max number of clients reached錯誤信息
    maxclients 128
17. 指定Redis最大內存限制,Redis在啟動時會把數據加載到內存中,達到最大內存后,Redis會先嘗試清除已到期或即將到期的Key,
當此方法處理 后,仍然到達最大內存設置,將無法再進行寫入操作,但仍然可以進行讀取操作。
Redis新的vm機制,會把Key存放內存,Value會存放在swap區
    maxmemory <bytes>
18. 指定是否在每次更新操作后進行日志記錄,Redis在默認情況下是異步的把數據寫入磁盤,如果不開啟,
可能會在斷電時導致一段時間內的數據丟失。因為 redis本身同步數據文件是按上面save條件來同步的,
所以有的數據會在一段時間內只存在于內存中。默認為no
    appendonly no
19. 指定更新日志文件名,默認為appendonly.aof
     appendfilename appendonly.aof
20. 指定更新日志條件,共有3個可選值: 
    no:表示等操作系統進行數據緩存同步到磁盤(快) 
    always:表示每次更新操作后手動調用fsync()將數據寫到磁盤(慢,安全) 
    everysec:表示每秒同步一次(折衷,默認值)

6.keepalived安裝(兩臺機器都同時安裝)

[root@redis_master ~]# wget http://www.keepalived.org/software/keepalived-1.2.20.tar.gz  
[root@redis_master ~]# tar -xf keepalived-1.2.20.tar.gz
[root@redis_master ~]# cd keepalived-1.2.20
[root@redis_master keepalived-1.2.20]# ./configure --prefix=/usr/local/keepalived 
[root@redis_master keepalived-1.2.20]# make && make install
[root@redis_master keepalived-1.2.20]# cp /usr/local/keepalived/sbin/keepalived   /usr/sbin/
[root@redis_master keepalived-1.2.20]# cp /usr/local/keepalived/etc/sysconfig/keepalived   /etc/sysconfig/
[root@redis_master keepalived-1.2.20]# cp  /usr/local/keepalived/etc/rc.d/init.d/keepalived  /etc/init.d/
[root@redis_master  keepalived-1.2.20]#  cp /usr/local/keepalived/etc/keepalived/keepalived.conf  /etc/keepalived/
[root@redis_master keepalived-1.2.20]# mkdir -p /etc/keepalived/log/
[root@redis_master keepalived-1.2.20]# mkdir -p /etc/keepalived/scripts/
添加日志
[root@redis_master keepalived-1.2.20]# vim /etc/sysconfig/keepalived
KEEPALIVED_OPTIONS="-D"
修改為
KEEPALIVED_OPTIONS="-D -d -S 0"
[root@redis_master keepalived-1.2.20]# vi /etc/rsyslog.conf
加入如下配置:
#keepalived -S 0
local0.* /var/log/keepalived.log
重啟日志服務
[root@redis_master keepalived-1.2.20]# /etc/init.d/rsyslog restart
監測日志文件是否生成
[root@redis_master keepalived-1.2.20]# ll /var/log/keepalived.log
-rw-------. 1 root root 0 Jun 21 19:46 /var/log/keepalived.log

keepalived已經安裝完畢

7.keepalived配置文件

redis主上keepalived配置文件

global_defs {
            lvs_id LVS_redis 80
           smtp_connect_timeout 30
        }
vrrp_script chk_redis { 
        script "sh /etc/keepalived/scripts/redis_check.sh"
        interval 1                                   
        weight 2
} 
 
vrrp_instance VI_1 { 
        state MASTER                         
        interface eth1                    
        virtual_router_id 60
        unicast_src_ip 192.168.155.205
        unicast_peer {
            192.168.155.206
        }
        priority 200     
        advert_int 1  
        track_script { 
            chk_redis                     
        } 
        virtual_ipaddress { 
             192.168.155.207                     
        }
        notify_master /etc/keepalived/scripts/redis_master.sh
        notify_backup /etc/keepalived/scripts/redis_backup.sh
        notify_fault  /etc/keepalived/scripts/redis_fault.sh
        notify_stop   /etc/keepalived/scripts/redis_stop.sh 
}

redis從上keepalived配置文件

global_defs {
            lvs_id LVS_redis 80
           smtp_connect_timeout 30
        }
vrrp_script chk_redis { 
        script "sh /etc/keepalived/scripts/redis_check.sh"
        interval 1                                    
        weight 2
} 
 
vrrp_instance VI_1 { 
        state MASTER                       
        interface eth1                         
        virtual_router_id 60
        priority 200       
        unicast_src_ip 192.168.155.206
        unicast_peer {
           192.168.155.205
        }
        advert_int 1  
        track_script { 
            chk_redis                     
        } 
        virtual_ipaddress { 
             192.168.155.207                    
        }
        notify_master /etc/keepalived/scripts/redis_master.sh
        notify_backup /etc/keepalived/scripts/redis_backup.sh
        notify_fault  /etc/keepalived/scripts/redis_fault.sh
        notify_stop   /etc/keepalived/scripts/redis_stop.sh 
}

以上是keepalived配置文件。

redis_master

redis_check.sh文件如下:

#!/bin/bash

SERV=keepalived
CHECK_TIME=2

check() {
    /usr/local/bin/redis-cli  ping > /dev/null 2>&1

    ret=$?

    if [ $ret -ne 0 ];then
        return $ret;

    fi
}

while [ $CHECK_TIME -ne 0 ];do
    let "CHECK_TIME -= 1"

    check
    REDIS_OK=$?

    if [ $REDIS_OK -eq 0 ];then
        exit $REDIS_OK
    else

        if [ $CHECK_TIME -eq 0 ];then
            /etc/init.d/$SERV stop
            exit $REDIS_OK
        fi
    fi
done

redis_stop.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_stop.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_stop.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.155.206 6379'" >> $LOGFILE
$REDISCLI SLAVEOF  192.168.155.206 6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to 192.168.155.206  ok..." >> $LOGFILE

redis_fault.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_fault.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_fault.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.155.206 6379'" >> $LOGFILE
$REDISCLI SLAVEOF  192.168.155.206 6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to 192.168.155.206  ok..." >> $LOGFILE

redis_backup.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_backup.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_backup.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.155.206 6379'" >> $LOGFILE
$REDISCLI SLAVEOF  192.168.155.206 6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to 192.168.155.206  ok..." >> $LOGFILE

redis_master.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_master.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_master.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.88.206 6379'" >> $LOGFILE
$REDISCLI SLAVEOF 192.168.155.206  6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Run slaveof no one,close master/slave" >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] wait other slave connect...." >> $LOGFILE

redis_slave

redis_check.sh文件如下:

#!/bin/bash

SERV=keepalived
CHECK_TIME=2

check() {
    /usr/local/bin/redis-cli  ping > /dev/null 2>&1

    ret=$?

    if [ $ret -ne 0 ];then
        return $ret;

    fi
}

while [ $CHECK_TIME -ne 0 ];do
    let "CHECK_TIME -= 1"

    check
    REDIS_OK=$?

    if [ $REDIS_OK -eq 0 ];then
        exit $REDIS_OK
    else

        if [ $CHECK_TIME -eq 0 ];then
            /etc/init.d/$SERV stop
            exit $REDIS_OK
        fi
    fi
done
redis_stop.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_stop.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_stop.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.155.205 6379'" >> $LOGFILE
$REDISCLI SLAVEOF  192.168.155.205 6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to 192.168.155.205  ok..." >> $LOGFILE
redis_fault.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_fault.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_fault.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.155.205 6379'" >> $LOGFILE
$REDISCLI SLAVEOF  192.168.155.205 6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to 192.168.155.205  ok..." >> $LOGFILE
redis_backup.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_backup.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_backup.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Being slave state..." >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.155.205 6379'" >> $LOGFILE
$REDISCLI SLAVEOF  192.168.155.205 6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] slave connect to 192.168.155.205  ok..." >> $LOGFILE
redis_master.sh文件如下:
#!/bin/bash
###/etc/keepalived/scripts/redis_master.sh
REDISCLI="/usr/local/bin/redis-cli "
LOGFILE="/etc/keepalived/log/redis-state.log"
pid=$$
 
echo "Run redis_master.sh" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver]" >> $LOGFILE
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[slaver] Run 'SLAVEOF 192.168.88.205 6379'" >> $LOGFILE
$REDISCLI SLAVEOF 192.168.155.205  6379 >> $LOGFILE  2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] Run slaveof no one,close master/slave" >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1
echo "`date +'%Y-%m-%d:%H:%M:%S'`|$pid|state:[master] wait other slave connect...." >> $LOGFILE
[root@redis_master scripts]# cd /etc/keepalived/scripts/
[root@redis_master scripts]# chmod +x *
[root@redis_master scripts]# /etc/init.d/keepalivded restart

測試階段:

1.    redis主從都啟動keepalived

redis_master
[root@redis_master scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d6:63:b6 brd ff:ff:ff:ff:ff:ff
    inet 192.168.155.205/24 brd 192.168.155.255 scope global eth1
    inet 192.168.155.207/32 scope global eth1
    inet6 fe80::20c:29ff:fed6:63b6/64 scope link 
       valid_lft forever preferred_lft forever

redis_slave
[root@redis_slave scripts]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:46:38:94 brd ff:ff:ff:ff:ff:ff
    inet 192.168.155.206/24 brd 192.168.155.255 scope global eth1
    inet6 fe80::20c:29ff:fe46:3894/64 scope link 
       valid_lft forever preferred_lft forever

2.    測試主從同步

redis_master
[root@redis_master scripts]# redis-cli
127.0.0.1:6379> set laopo hyl
OK
127.0.0.1:6379> get laopo
"hyl"
127.0.0.1:6379>
redis_slave
[root@redis_slave ~]# redis-cli 
127.0.0.1:6379> get laopo
"hyl"
127.0.0.1:6379>

redis主從已經測試成功

可以多設置幾個值(在down之前):

127.0.0.1:6379> set 11 22
OK
127.0.0.1:6379> set 22 33
OK
127.0.0.1:6379> set 33 44
OK
127.0.0.1:6379> set 44 55
OK
127.0.0.1:6379> get 11
"22"
127.0.0.1:6379> get 22
"33"
127.0.0.1:6379> get 33
"44"
127.0.0.1:6379> get 44
"55"

3.測試redis主down

redis_master
[root@redis_master ~]# /etc/init.d/redis stop
[root@redis_master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d6:63:b6 brd ff:ff:ff:ff:ff:ff
    inet 192.168.155.205/24 brd 192.168.155.255 scope global eth1
    inet6 fe80::20c:29ff:fed6:63b6/64 scope link 
       valid_lft forever preferred_lft forever
[root@redis_master ~]# ss -ln
State       Recv-Q Send-Q      Local Address:Port     Peer Address:Port 
LISTEN      0      128        :::22           :::*     
LISTEN      0      128         *:22           *:*     
LISTEN      0      100        ::1:25           :::*     
LISTEN      0      100        127.0.0.1:25        *:*     
LISTEN      0      50         *:3306          *:*
redis_slave
[root@redis_slave ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:46:38:94 brd ff:ff:ff:ff:ff:ff
    inet 192.168.155.206/24 brd 192.168.155.255 scope global eth1
    inet 192.168.155.207/32 scope global eth1
    inet6 fe80::20c:29ff:fe46:3894/64 scope link 
       valid_lft forever preferred_lft forever
[root@redis_slave ~]# ss -ln
State       Recv-Q Send-Q      Local Address:Port     Peer Address:Port 
LISTEN      0      128        :::22                   :::*     
LISTEN      0      128         *:22                  *:*     
LISTEN      0      100        ::1:25                  :::*     
LISTEN      0      100        127.0.0.1:25               *:*     
LISTEN      0      50         *:3306                  *:*
LISTEN      0      128        *:6379                     *:*             
LISTEN      0      128                :::6379         :::*

vip已經漂移至 redis_slave,測試redis主從是否切換;

redis_slave
[root@redis_slave ~]# redis-cli 
127.0.0.1:6379> set 123 123
OK
127.0.0.1:6379> get 123
"123"
127.0.0.1:6379> get 11
"22"
127.0.0.1:6379> get 22
"33"
127.0.0.1:6379> get 33
"44"
再down之前,多設置幾個鍵值
127.0.0.1:6379> set 1010 1010
OK
127.0.0.1:6379> set 2020 2020
OK
127.0.0.1:6379> set 3030 3030
OK
127.0.0.1:6379> get 1010
"1010"
127.0.0.1:6379> get 2020
"2020"
127.0.0.1:6379> get 3030
"3030"
redis_master
[root@redis_master ~]# /etc/init.d/redis start
[root@redis_master ~]# /etc/init.d/keepalived start
Starting keepalived:                         [  OK  ]
[root@redis_master ~]# redis-cli 
127.0.0.1:6379> get 123
"123"
127.0.0.1:6379> get 11
"22"
127.0.0.1:6379> get 33
"44"
127.0.0.1:6379> get 44
"55"
127.0.0.1:6379> get 1010
"1010"
127.0.0.1:6379> get 2020
"2020"
127.0.0.1:6379> get 3030
"3030"

redis數據不會丟失,redis從立馬會接管vip提供服務。redis主從角色互調。

4.redis主恢復后,一直處于slave狀態,如果redis從down掉,redis主是否會重新奪取vip,并且數據自動同步回來。

redis_slave
[root@redis_slave ~]# /etc/init.d/redis stop
[root@redis_slave ~]# /etc/init.d/redis start
[root@redis_slave ~]# /etc/init.d/keepalived start
Starting keepalived:                    [  OK  ]
[root@redis_slave ~]# i a
bash: i: command not found
[root@redis_slave ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:46:38:94 brd ff:ff:ff:ff:ff:ff
    inet 192.168.155.206/24 brd 192.168.155.255 scope global eth1
    inet6 fe80::20c:29ff:fe46:3894/64 scope link 
       valid_lft forever preferred_lft forever
vip已經漂移至redis_master
redis_master
[root@redis_master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:d6:63:b6 brd ff:ff:ff:ff:ff:ff
    inet 192.168.155.205/24 brd 192.168.155.255 scope global eth1
    inet 192.168.155.207/32 scope global eth1
    inet6 fe80::20c:29ff:fed6:63b6/64 scope link 
       valid_lft forever preferred_lft forever
vip又重新綁定在redis_master主上

測試現在redis主從是否同步數據,和之前的數據是否存在;

redis_master
[root@redis_master ~]# redis-cli 
127.0.0.1:6379> set last 111
OK
127.0.0.1:6379> get last
"111"
127.0.0.1:6379> get 1010
"1010"
127.0.0.1:6379> get 2020
"2020"
127.0.0.1:6379> get 11
"22"
127.0.0.1:6379> get 22
"33"
127.0.0.1:6379> get 33
"44"
redis_slave
[root@redis_slave ~]# redis-cli 
127.0.0.1:6379> get last
"111"
127.0.0.1:6379> get 11
"22"
127.0.0.1:6379> get 22
"33"
127.0.0.1:6379> get 123
"123"
127.0.0.1:6379> get 1010
"1010"
127.0.0.1:6379> get 2020
"2020"
127.0.0.1:6379>

數據不會丟失,全部都同步上。

redis+keepalived 主主模型,其實redis現在不支持主主,只是我們可以理解為redis主主。可以很智能的自動切換,redis主從。主要2臺redis不同時掛掉,就不會丟失數據及對數據造成影響。

此方案,已經在線上使用,大家可以參考下文檔。

原創文章,作者:Net20_赤羽,如若轉載,請注明出處:http://www.www58058.com/19183

(3)
Net20_赤羽Net20_赤羽
上一篇 2016-06-23
下一篇 2016-06-23

相關推薦

  • linux文件權限

                                                      &nbsp…

    Linux干貨 2016-08-04
  • 用戶和組的四大配置文件簡介

    一. 用戶的由來 linux系統擁有的就是資源,最重要的事就是對資源的分配,資源分給誰?在linux上資源的訪問是對用戶賦予不同的權限實現,也就是說能訪問資源的單位是用戶。那用戶在獲取資源之前要實現證明自己是本用戶,這個過程稱為認證,他通過密碼和用戶名實現。在用戶登錄時會將用戶輸入的用戶名和密碼進行校驗,校驗過程就是將輸入的用戶名和密碼與linux系統上記錄…

    Linux干貨 2016-10-24
  • 修改Linux命令終端提示符

    作業1. 設置自己的終端提示符,要求字符終端登錄時:     a> 需要帶顏色     b> 需要顯示當前執行到了第幾條命令     c> 顯示當前登錄終端,主機名和當前時間     這可以通…

    Linux干貨 2016-10-17
  • 馬哥教育網絡20期+第7周練習博客

    1、創建一個10G分區,并格式為ext4文件系統;    (1) 要求其block大小為2048, 預留空間百分比為2, 卷標為MYDATA, 默認掛載屬性包含acl;    (2) 掛載至/data/mydata目錄,要求掛載時禁止程序自動運行,且不更新文件的訪問時間戳; [root@7b ~]#&nbsp…

    Linux干貨 2016-07-24
  • 磁盤管理

    磁盤設備 一切皆文件 所有的Linux中的設備都可以使用下面命令進行操作:open(), read(), write(), close()(這些是C的函數) 塊設備:隨機訪問 字符設備:線性訪問 設備號碼: 主設備號:major number,標識設備類型 8是主要設備編號,代表類型 次設備號:minor number…

    Linux干貨 2016-09-01
  • N25-第6周博客作業

    N25-第6周博客作業 vim:     模式化的編輯器         基本模式:             編輯模式,…

    Linux干貨 2017-01-09
欧美性久久久久