redisプライマリスレーブによる10秒のチェックとリカバリ

3868 ワード

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を判断する時間を決めなければなりません.
より良いredis主従実装方法があれば、共有してください.