redisプライマリスレーブ構成およびkeepalivedによるredis自動切替、redisプライマリスレーブによる10秒のチェックとリカバリ

15355 ワード

一:環境紹介:
Master: 192.168.1.4
Slave: 192.168.1.5
Virtural IP Address (VIP): 192.168.1.253
二:設計構想:
MasterとSlaveが正常に動作している場合、Masterはサービスを担当し、SlaveはStandbyを担当する.
Masterがオフにすると、Slaveはサービスを引き継ぎ、主従レプリケーション機能をオフにします.
Masterが正常に回復すると、Slaveからデータを同期し、データを同期した後、マスタコピー機能をオフにし、Masterアイデンティティを回復し、同時にSlaveはMaster同期データが完了するのを待ってからSlaveアイデンティティを回復する.
そして順番にループします.
このようにするには、MasterとSlaveの両方でローカライズポリシーをオンにする必要があります.そうしないと、互いに自動的に切り替える過程で、ローカライズをオンにしていない側が他方のデータを空にし、データが完全に失われます.
三:構成をインストールする前に準備する
1.プライマリ・サーバ192.168.1.4で次の操作を行います.
echo "192.168.1.4 test01">>/etc/hosts
echo "192.168.1.5 test">>/etc/hosts
2.サーバ192.168.1.5から以下の操作を行う
echo "192.168.1.4 test01">>/etc/hosts
echo "192.168.1.5 test">>/etc/hosts
四:プライマリサーバ構成redis
1.インストールredisパッケージのダウンロード
wget http://download.redis.io/releases/redis-2.8.12.tar.gztar xf redis-2.8.12.tar.gz 
cd redis-2.8.12
make && make install
cd src/
cp redis-server redis-cli redis-benchmark redis-check-aof redis-check-dump /usr/local/bin
cd /usr/local/bin
ls -ll
        redis.conf     /etc/redis.conf
cp /root/redis-2.8.12/redis.conf /etc/redis.conf
   /etc/redis.conf       daemonize no    daemonize yes
          redis-server 。

      init.d      :
vim /etc/init.d/redis-server
#!/usr/bin/env bash
#
# redis start up the redis server daemon
#
# chkconfig: 345 99 99
# description: redis service in /etc/init.d/redis \
#             chkconfig --add redis or chkconfig --list redis \
#             service redis start  or  service redis stop
# processname: redis-server
# config: /etc/redis.conf

PATH=/usr/local/bin:/sbin:/usr/bin:/bin

REDISPORT=6379
EXEC=/usr/local/bin/redis-server
REDIS_CLI=/usr/local/bin/redis-cli

PIDFILE=/var/run/redis.pid
CONF="/etc/redis.conf"
#make sure some dir exist
if [ ! -d /var/lib/redis ] ;then
    mkdir -p /var/lib/redis
    mkdir -p /var/log/redis
fi

case "$1" in
    status)
        ps -A|grep redis
        ;;
    start)
        if [ -f $PIDFILE ]
        then
                echo "$PIDFILE exists, process is already running or crashed"
        else
                echo "Starting Redis server..."
                $EXEC $CONF
        fi
        if [ "$?"="0" ]
        then
              echo "Redis is running..."
        fi
        ;;
    stop)
        if [ ! -f $PIDFILE ]
        then
                echo "$PIDFILE does not exist, process is not running"
        else
                PID=$(cat $PIDFILE)
                echo "Stopping ..."
                $REDIS_CLI -p $REDISPORT SHUTDOWN
                while [ -x ${PIDFILE} ]
               do
                    echo "Waiting for Redis to shutdown ..."
                    sleep 1
                done
                echo "Redis stopped"
        fi
        ;;
   restart|force-reload)
        ${0} stop
        ${0} start
        ;;
  *)
    echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
        exit 1
esac

chmod o+x/etc/init.d/redis-server
chkconfig --add redis-server
service redis-server start 
五:サーバーからredisを構成する
サーバから、構成は同じで、/etc/redisを変更するだけです.conf中
slaveeofに変更
slaveof 192.168.1.4 6379
次に、サーバからのredisサービスを開始します.
start redis-server start
六:redis主従テストを行う
#プライマリサーバ
redis-cli -p 6379 set hello world
#サーバから
redis-cli -p 6379 get hello
"world"
#プライマリサーバ
redis-cli -p 6379 set hello world2
#サーバから
redis-cli -p 6379 get hello
"world2"
redis-cli -p 6379 set hello world
(error) READONLY You can't write against a read only slave.
プライマリスレーブredisサーバの構成に成功しました.構成の1つはスレーブサーバが読み取り専用であるため、サーバからデータを設定することができず、データのみを読み取ることができます.
七:keepalivedのインストールと構成
1.MasterとSlaveにKeepalivedを取り付ける
$ yum install keepalived -y
2.デフォルトではkeepalivedのインストールが完了した後にプロファイルがないため、手動で作成する必要があります.
まず、Masterに次のプロファイルを作成します.
$  vim/etc/keepalived/keepalived.conf
! Configuration File for keepalived

vrrp_script chk_redis {
    script "/etc/keepalived/scripts/redis_check.sh"     ###       
    interval 2                                          ###    
    }

vrrp_instance VI_1 {
    state MASTER                 ###   MASTER  
    interface eth1                ###         
    virtual_router_id 51
    priority 100            ###     
    authentication {
        auth_type PASS        ###    
        auth_pass 1111        ###  
    }

track_script {
    chk_redis             ###       chk_redis  
    }

    virtual_ipaddress {
        192.168.1.253         ######VIP 
    }

         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
}

3.次に、Slaveに次のプロファイルを作成します.
$ vim/etc/keepalived/keepalived.conf
! Configuration File for keepalived

vrrp_script chk_redis {
    script "/etc/keepalived/scripts/redis_check.sh"     ###      
    interval 2                   ###    
    }

vrrp_instance VI_1 {
    state BACKUP         ###   BACKUP   
    interface eth1       ###    
    virtual_router_id 51
    priority 10          ### MASTRE       
    authentication {
        auth_type PASS
        auth_pass 1111        ###   MASTRE    
    }

track_script {
    chk_redis        ###       chk_redis  
    }

    virtual_ipaddress {
        192.168.1.253   ####vip
    }

         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

}

4.MasterとSlaveにRedisを監視するスクリプトを作成する
$  mkdir/etc/keepalived/scripts
$  vim/etc/keepalived/scripts/redis_check.sh
#!/bin/bash  
ALIVE=`/usr/local/bin/redis-cli PING`  
if [ "$ALIVE" == "PONG" ]; then 
echo $ALIVE  
exit 0  
else 
echo $ALIVE  
exit 1  
fi

5.次の重要なスクリプトを作成します.
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はステータスを変換するときにステータスに従って呼び出すからです.
Master状態になるとnotify_が呼び出されますmaster
Backup状態に入るとnotify_が呼び出されますbackup
異常が検出された場合はFaultステータスコールnotify_fault
Keepalivedプログラムが終了するとnotify_を呼び出すstop
1)まず、Redis Masterにnotity_を作成するmasterとnotify_backupスクリプト:
$  vim/etc/keepalived/scripts/redis_master.sh
#!/bin/bash
REDISCLI="/usr/local/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"
echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1

echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.1.5 6379 >> $LOGFILE  2>&1
sleep 10 #  10                    

echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

$  vim/etc/keepalived/scripts/redis_backup.sh
#!/bin/bash  
REDISCLI="/usr/local/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"

echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1

sleep 15 #  15                      
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.1.5 6379 >> $LOGFILE  2>&1

2)Redis Slaveにnotity_を作成するmasterとnotify_backupスクリプト:
$  vim/etc/keepalived/scripts/redis_master.sh
#!/bin/bash  
REDISCLI="/usr/local/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"

echo "[master]" >> $LOGFILE
date >> $LOGFILE
echo "Being master...." >> $LOGFILE 2>&1

echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.1.4 6379 >> $LOGFILE  2>&1
sleep 10 #  10                    

echo "Run SLAVEOF NO ONE cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF NO ONE >> $LOGFILE 2>&1

$  vim/etc/keepalived/scripts/redis_backup.sh
#!/bin/bash  
REDISCLI="/usr/local/bin/redis-cli"
LOGFILE="/var/log/keepalived-redis-state.log"

echo "[backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being slave...." >> $LOGFILE 2>&1

sleep 15 #  15                      
echo "Run SLAVEOF cmd ..." >> $LOGFILE
$REDISCLI SLAVEOF 192.168.1.4 6379 >> $LOGFILE  2>&1

3)その後、MasterとSlaveで次のように同じスクリプトを作成します.
$  vim/etc/keepalived/scripts/redis_fault.sh
#!/bin/bash  
LOGFILE=/var/log/keepalived-redis-state.log
echo "[fault]" >> $LOGFILE
date >> $LOGFILE

$  vim/etc/keepalived/scripts/redis_stop.sh
#!/bin/bash  
LOGFILE=/var/log/keepalived-redis-state.log
echo "[stop]" >> $LOGFILE
date >> $LOGFILE

6.プライマリ・サーバ上でスクリプトに実行可能権限を付与するには、次の手順に従います.
$  chmod +x/etc/keepalived/scripts/*.sh
7.関連機能テストを行う
MasterとslaveのRedisを起動
$  /etc/init.d/redis start
MasterとslaveのKeepalivedを起動
$  /etc/init.d/keepalived start
VIPでRedisを接続してみます.
$ redis-cli -h 192.168.0.253 INFO
接続に成功し、Slaveも接続されました.
role:master
slave0:192.168.1.5,6379,online
いくつかのデータを挿入してみます.
$ redis-cli -h 192.168.0.253 SET Hello Redis
OK
VIPからデータを読み込む
$ redis-cli -h 192.168.0.253 GET Hello
"Redis"
Masterからデータを読み込む
$ redis-cli -h 192.168.0.1 GET Hello
"Redis"
Slaveからデータを読み込む
$ redis-cli -h 192.168.0.2 GET Hello
"Redis"
8.関連故障を模擬して、機能テストを行う
マスター上のRedisプロセスを殺す:
$  killall -9 redis-server
MasterのKeepalivedログの表示
$ tail -f/var/log/keepalived-redis-state.log
[fault]
Thu Sep 27 08:29:01 CST 2012
同時にSlaveのログが表示されます.
$ tail -f/var/log/keepalived-redis-state.log
[master]
2014年07月07日月曜日16:42:52 CST
Being master....
Run SLAVEOF cmd ...
OK Already connected to specified master
Run SLAVEOF NO ONE cmd ...
OK
その後、Slaveはサービスを引き継ぎ、Masterの役割を果たしていることがわかります.
$ redis-cli -h 192.168.1.253 INFO
$ redis-cli -h 192.168.1.5 INFO
role:master
そしてMasterのRedisプロセスを復元します
$  /etc/init.d/redis start
MasterのKeepalivedログの表示
$ tail -f/var/log/keepalived-redis-state.log
[master]
2014年07月07日月曜日16:48:08 CST
Being master....
Run SLAVEOF cmd ...
OK
Run SLAVEOF NO ONE cmd ...
OK
同時にSlaveのログが表示されます.
$ tail -f/var/log/keepalived-redis-state.log
[backup]
Fri Sep 28 14:16:37 CST 2012
Being slave....
Run SLAVEOF cmd ...
OK
現在のMasterは、Masterの役割を再開し、フェイルオーバー、自動リカバリが成功していることがわかりました.
参照先:http://chwshuang.iteye.com/blog/1881169
     http://birdinroom.blog.51cto.com/7740375/1401663 
     http://birdinroom.blog.51cto.com/7740375/1401493 
Saltstack pillarによるredisマルチインスタンス導入
http://binbin158.blog.51cto.com/2659767/1383885 
redisプライマリスレーブによる10秒のチェックとリカバリ
redisプライマリ・スレーブ・アーキテクチャ
問題:redis downが再起動するとkey値が復元され、時間が遅延し、downマシン間の値が失われます.
実験環境では,主従は1台のサーバ上で,異なるポートを利用する.
ソリューション:redisマスターはまだ完璧ではありません.私たちはredisマスターを利用して主にredisバックアップを行い、masterがダウンタイムした後、10 s以内にできるだけkey値を回復し、主に読み書きを行い、高速読み書きを実現し、バックアップ方式を一切せず、簡単で実用的なrdb方式からバックアップを実現します.
構想原理:
redisには2つの持続化方式があり、rdbとaofモードは、aofモードの成長が速すぎて回復が遅いことを考慮して、上からrdbモードを行い、メインdownの後、スクリプトはメインの状態をチェックし、その後、上からbgsaveを行い、上のrdbファイルcopyからメインのdataディレクトリに、メインを再起動します.主上keyが数量に値するかどうかを判断し、上の数量と同じかどうかを判断することで、正常に回復したかどうかを判断し、keyが完全に回復する価値があることを実現することができる.バックアップ方式は、1時間に1回copy上のrbdファイルから、1時間に1回のバックアップを行います.
シナリオの構想は主に上述の構想の原理を実現して、シナリオは少し違和感があって、2主をして、1したredis従.
#!/bin/bash
 
DATE=`date +%Y%m%d%M%s`
REDIS_DIR=/usr/local/redis
REDIS2_DIR=/usr/local/redis2
BIN_DIR=/usr/local/redis/bin
DATA1_DIR=/usr/local/redis/data
DATA2_DIR=/usr/local/redis2/data
PORT1=6378
PORT2=6379
 
function BACKUP_RDB {
    ps -ef |grep $PORT2 >/dev/null
    if  [ $? -eq 0 ];then
        ${BIN_DIR}/redis-cli -p $PORT2 bgsave >/dev/null
        if [ $? -eq 0 ];then
            echo -e "\033[31m MASTER REDIS DOWN AND SLAVE bgsave DONE\033[0m"
            ${BIN_DIR}/redis-cli -p $PORT2 SLAVEOF NO ONE >/dev/null
        fi
     fi
}
 
function CP_RDB {
    [ -d ${DATA1_DIR}/redisbackup ]  || mkdir ${DATA1_DIR}/redisbackup
    if [ -f $DATA2_DIR/dump.rdb ];then
        mv ${DATA1_DIR}/dump.rdb  ${DATA1_DIR}/redisbackup/dump.rdb.$DATE
        cp ${DATA2_DIR}/dump.rdb  ${DATA1_DIR}/
    fi
}
 
function  START_REDIS {
    KEY2_NUM=`${BIN_DIR}/redis-cli -p $PORT2 INFO  |grep db[0-9]*.key |awk -F[:=,] '{total+=$3}END{print total}'`
    ${BIN_DIR}/redis-server ${REDIS_DIR}/etc/redis.conf
    netstat -tnlp |grep "$PORT1" >/dev/null
    a=$?
    if [ $a -ne 0 ];then
        while [ $a -ne 0 ];do
            sleep 2
            netstat -tnlp | grep "127.0.0.1:$PORT1" 1>/dev/null 2>/dev/null
            a=$?
        done
        echo -e "\033[32m MASTER REDIS RUNNING ........\033[0m"
        sleep 7
        KEY1_NUM=`${BIN_DIR}/redis-cli -p $PORT1  INFO  |grep db[0-9]*.key |awk -F[:=,] '{total+=$3}END{print 
 
total}'`
#        echo ${KEY1_NUM}
        if [ $KEY1_NUM -ge $KEY2_NUM ];then
            ${BIN_DIR}/redis-cli -p $PORT2 SLAVEOF 127.0.0.1 $PORT1 >/dev/null
            echo -e "\033[32m MASTER AND SLAVE are Normal sync \033[0m"
        else
            echo -e "\033[31m KEY NUM are not equal, MASTER AND SLAVE are not Normal sync,place to check ! \033[0m"
            break
        fi
    else
        echo -e "\033[32m MASTER REDIS RUNNING ........\033[0m"
        sleep 7
        KEY1_NUM=`${BIN_DIR}/redis-cli -p $PORT1 INFO  |grep db[0-9]*.key |awk -F[:=,] '{total+=$3}END{print total}'`
#        echo ${KEY1_NUM}
        if [ $KEY1_NUM -ge $KEY2_NUM ];then
            ${BIN_DIR}/redis-cli -p $PORT2 SLAVEOF 127.0.0.1 $PORT1 >/dev/null
            echo -e "\033[32m MASTER AND SLAVE are Normal sync \033[0m"
        else
            echo -e "\033[31m KEY NUM are not equal, MASTER AND SLAVE are not Normal sync,place to check ! \033[0m"
            break
        fi
    fi
}
 
 
while true;do
    sleep 10
    netstat -tnlp | grep "127.0.0.1:$PORT1" 1>/dev/null 2>/dev/null
    TRAP1=$?
    ps -ef |grep "$PORT1" >/dev/null
    TRAP2=$?
    if [ $TRAP1 -ne  0 ] || [ $TRAP2 -ne  0 ];then
        #echo redis-master down
        BACKUP_RDB
        CP_RDB
        START_REDIS
    fi
done

回復の過程で、主のkeyと主ダウンタイム後のkeyを比較して、正常に回復したかどうかを判断し、
出会った問題:回復の過程の中で、主keyの値はずっと従のkeyの値より小さいが、主起動は完全に正常で、keyの値も完全に同じで、考えてみると、プログラムの実行問題で、スクリプトの実行が速すぎて、比較まで実行する時、keyの数は完全に回復していないで、ただ時間の問題で、だからsleepを実行して3秒後、すべて正常です.みんなは自分のkeyの数の大きさによってsleepを判断する時間を決めなければなりません.