Redis高可用方案:使用Keepalived實現主備雙活

sowler發表於2024-08-30

注意:請確保已經安裝Redis和keepalived,本文不在介紹如何安裝。

1、使用版本說明

Redis版本:5.0.2

Keepalived版本:1.3.5

Linux 版本:Centos7.9

檢視Redis版本:

/usr/local/redis/bin/redis-cli -v

檢視Keepalived版本資訊:

rpm -qa|grep keepalived 或者 keepalived -v

2、功能實現說明:

  • 使用Keepalived提供虛擬IP對外訪問Redis
  • Redis搭建主從資料同步,主用來讀寫資料 、從主要進行主資料同步備份。
  • 當主出現當機,Keepalived虛擬IP自動指向從伺服器。從伺服器臨時變為主伺服器繼續工作。
  • 待主伺服器重新啟動後,Keepalived虛擬IP重新指向主伺服器。主伺服器同步從伺服器資料後繼續工作。從伺服器由臨時主變為從繼續進行主資料同步備份。

3、說明圖

Keepalived會生成一個虛擬IP。客戶端需要訪問虛擬IP進行Redis連線:

3.1 、主和備伺服器執行中

3.2、主當機,備伺服器執行中

3.3、 主恢復,備伺服器執行中

4、搭建Redis主從

首先確保兩臺伺服器都安裝了Redis服務,Redis的埠號和密碼兩臺伺服器必須保持一致。我這裡兩臺伺服器都是使用埠號:6379和密碼:1234qwer

伺服器IP:

主伺服器:192.168.42.130

備伺服器:192.168.42.133

4.1、 修改配置檔案

首先需要修改備伺服器redis配置檔案,把備伺服器redis掛載到主伺服器redis下面實現主從配置。

進入redis目錄

cd /usr/local/redis/

修改redis.conf檔案

vim redis.conf

找到replicaof和masterauth屬性進行配置

# replicaof <masterip> <masterport>
replicaof 192.168.42.130 6379
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the replica to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the replica request.
#
# masterauth <master-password>
masterauth "1234qwer"

replicaof:主伺服器IP和埠號

masterauth:用於在進行主從複製時,保護Redis主節點的資料安全。密碼就是設定相同的主從節點的密碼。以確保只有經過授權的從節點才能夠連線到主節點。如果不配置,會導致節點連線失敗:master_link_status:down

透過登入redis輸入:info replication 可以檢視Redis叢集配置資訊。如果搭建成功,會顯示節點資訊。

注意: 在Redis 5.0及以上版本,SLAVEOF 命令已經被廢棄,並且在伺服器上使用該命令會導致命令失效。所以在Redis 5.0及以上版本,設定複製的正確方法是使用 REPLICAOF 命令。為了相容舊版本,透過配置的方式仍然支援 slaveof,但是透過命令的方式則不行了。

4.2、驗證主從複製功能

驗證方式:登入主伺服器Redis,插入一條key資料。在備伺服器中登入Redis進行透過該key進行查詢,檢視是否獲取到資料。如果資料獲取成功,說明Redis主從複製搭建成功。

進入主伺服器登入redis

/usr/local/redis/bin/redis-cli

進行密碼認證

auth 1234qwer

輸出OK,表示認證成功。存入資料

set verify-key "Test Verify is Success"

輸出OK,表示插入成功。接下來登入備伺服器檢視資料。進入備伺服器登入redis:

/usr/local/redis/bin/redis-cli

進行密碼認證

auth 1234qwer

輸出OK,表示認證成功。獲取key資料

get verify-key

輸出:"Test Verify is Success",說明Redis主從搭建成功。

5、配置Keepalived資訊

/etc/keepalived目錄中存放keepalived.conf檔案。在該目錄下建立scripts_redis資料夾,目錄 /etc/keepalived/scripts_redis,將 redis_stop.sh 、redis_master.sh、redis_fault.sh 、redis_check.sh 、redis_backup.sh 放入scripts_redis檔案目錄下。

5.1 主伺服器配置

編寫keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id redis-master #唯一標識 注意主備服務名不可相同
   script_user root
   enable_script_security
}

vrrp_script redis_check { #指令碼檢測名稱,下方呼叫必須和這個名稱一致
    script "/etc/keepalived/scripts_redis/redis_check.sh" #監聽redis是否啟動指令碼路徑
    interval 4  #監聽心跳
    weight -5
    fall 3
    rise 2
}

vrrp_instance VI_redis {
    state MASTER    #當前keepalived狀態  MASTER 或者 BACKUP
    interface eth0  #網路卡名稱根據實際情況設定可透過命令ifconfig檢視
    virtual_router_id 21
    priority 110	#權重 主服務要高於備服務
    garp_master_refresh 10
    garp_master_refresh_repeat 2
    advert_int 1
    nopreempt
    unicast_src_ip 192.168.42.130 #單播模式 當前伺服器主伺服器IP地址
    unicast_peer {
        192.168.42.133 #備伺服器Ip
    }
	
    authentication {  #keepalived之間通訊的認證賬號、密碼
        auth_type PASS
        auth_pass 1111
    }
	
    virtual_ipaddress {
        192.168.42.161	#虛擬IP地址 客戶端統一的訪問地址
    }
	
    garp_master_delay 1
    garp_master_refresh 5
	track_interface {
        eth0	#網路卡
    }
	
    track_script {
        redis_check #指令碼檢測呼叫名稱
    }
	
    notify_master /etc/keepalived/scripts_redis/redis_master.sh	#master指令碼  keepalived設定的狀態為master時觸發或者master停止後,backup升級為master時觸發
    notify_backup /etc/keepalived/scripts_redis/redis_backup.sh #backup指令碼  keepalived設定的狀態為backup時觸發
    notify_fault /etc/keepalived/scripts_redis/redis_fault.sh #fault指令碼
    notify_stop /etc/keepalived/scripts_redis/redis_stop.sh  #stop指令碼 keepalived停止時觸發
	   
}

編寫 redis_master.sh,當主指令碼啟動時,需要先同步備伺服器redis資料後,在設定為主節點進行啟動:

#!/bin/bash

LOGFILE=/var/log/keepalived-redis-status.log
REDISCLI="/usr/local/redis/bin/redis-cli"

echo "Running redis_master.sh..." >>$LOGFILE
echo "[Master]" >> $LOGFILE
date >> $LOGFILE
echo "Being Master..." >> $LOGFILE
echo "Running SLAVEOF cmd..." >> $LOGFILE
$REDISCLI -h 192.168.42.130 -p 6379 -a 1234qwer CONFIG SET masterauth "1234qwer" 2>&1
$REDISCLI -h 192.168.42.130 -p 6379 -a 1234qwer REPLICAOF  192.168.42.133 6379 2>&1

sleep 5s

echo "Run slaveof no one cmd..." >>$LOGFILE

$REDISCLI -h 192.168.42.130 -p 6379 -a 1234qwer REPLICAOF NO ONE >>$LOGFILE 2>&1

echo "Finished running redis_master.sh..." >>$LOGFILE

編寫redis_backup.sh,

#!/bin/bash

LOGFILE=/var/log/keepalived-redis-status.log
REDISCLI="/usr/local/redis/bin/redis-cli"
echo "Running redis_bakcup.sh..." >>$LOGFILE
echo "[Backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being Slave..." >> $LOGFILE
echo "Run SLAVEOF cmd..." >> $LOGFILE
$REDISCLI -h 192.168.42.130 -p 6379 -a 1234qwer CONFIG SET masterauth "1234qwer"  >>$LOGFILE 2>&1
$REDISCLI -h 192.168.42.130 -p 6379 -a 1234qwer REPLICAOF 192.168.42.133 6379 >>$LOGFILE 2>&1
echo "Finished running redis_backup.sh..." >>$LOGFILE

5.2、備伺服器配置

編寫keepalived.conf

! Configuration File for keepalived

global_defs {
   router_id redis-slave #唯一標識 注意主備服務名不可相同
   script_user root
   enable_script_security
}

vrrp_script redis_check {
    script "/etc/keepalived/scripts_redis/redis_check.sh" #監聽redis是否啟動指令碼路徑
    interval 4 #監聽心跳
    weight -5
    fall 3  
    rise 2
}

vrrp_instance VI_redis {
    state BACKUP  #當前keepalived狀態 設定為BACKUP
    interface eth0
    virtual_router_id 21
    priority 100
    garp_master_refresh 10
    garp_master_refresh_repeat 2
    advert_int 1
    nopreempt
    unicast_src_ip 192.168.42.133 #單播模式 當前伺服器IP地址
    unicast_peer {
        192.168.42.130 #主伺服器Ip
    }
	
	
    authentication {
        auth_type PASS
        auth_pass 1111
    }
	
    virtual_ipaddress {
        192.168.42.161 #虛擬IP地址 客戶端統一的訪問地址
    }
	
    garp_master_delay 1
    garp_master_refresh 5

    track_interface {
        eth0
    }

    track_script {
        redis_check
    }
	
    notify_master /etc/keepalived/scripts_redis/redis_master.sh
    notify_backup /etc/keepalived/scripts_redis/redis_backup.sh
    notify_fault /etc/keepalived/scripts_redis/redis_fault.sh 
    notify_stop /etc/keepalived/scripts_redis/redis_stop.sh 
}


編寫redis_master.sh

#!/bin/bash
# LOGFILE檔案需要跟據實際情況更改
LOGFILE=/var/log/keepalived-redis-status.log
REDISCLI="/usr/local/redis/src/redis-cli"

echo "Running redis_master.sh..." >>$LOGFILE
echo "[Master]" >> $LOGFILE
date >> $LOGFILE
echo "Begin Master ..." >> $LOGFILE
echo "Run slaveof no one cmd...">>$LOGFILE
# SLAVEOF 5.0以上已經棄用 REPLICAOF 
$REDISCLI -h 192.168.42.133 -p 6379 -a 1234qwer REPLICAOF  NO ONE >>$LOGFILE 2>&1
echo "Finished running redis_master.sh..." >>$LOGFILE

編寫redis_backup.sh

#!/bin/bash

LOGFILE=/var/log/keepalived-redis-status.log
REDISCLI="/usr/local/redis/src/redis-cli"

echo "Running redis_bakcup.sh..." >>$LOGFILE
echo "[Backup]" >> $LOGFILE
date >> $LOGFILE
echo "Being Slave..." >> $LOGFILE
sleep 15s #休眠15秒,確保主伺服器指令碼redis_master.sh執行完畢後在執行主從命令
echo "Run SLAVEOF cmd..." >> $LOGFILE
# SLAVEOF 5.0已經棄用 改為:REPLICAOF
$REDISCLI -h 192.168.42.133 -p 6379 -a 1234qwer CONFIG SET masterauth "1234qwer"  >>$LOGFILE 2>&1
$REDISCLI -h 192.168.42.133 -p 6379 -a 1234qwer REPLICAOF  192.168.42.130 6379 >>$LOGFILE 2>&1
echo "Finished running redis_backup.sh..." >>$LOGFILE
5.3、編寫驗證Redis是否啟動指令碼

編寫redis_check.sh指令碼,透過監聽埠號判斷(主備一致)

#!/bin/bash
LOGFILE=/var/log/check-redis-status.log
echo "Running redis_check.sh..." >> $LOGFILE
date >> $LOGFILE
CHECK=$(ss -tnlp|grep 6379)
if [ $? -ne 0 ]; then
   echo "redis-server is not running..." >> $LOGFILE
   systemctl stop keepalived.service
   exit 1
else
   echo "redis-server is running..." >> $LOGFILE
   exit 0
fi
echo "Finished running redis_check.sh..." >> $LOGFILE
5.4 其他指令碼

編寫 redis_fault.sh (主備一致)

#!/bin/bash

LOGFILE=/var/log/keepalived-redis-status.log
echo "Running redis_fault.sh..." >>$LOGFILE
echo "[Fault]" >> $LOGFILE
date >> $LOGFILE
echo "Finished running redis_fault.sh..." >> $LOGFILE

編寫 redis_stop.sh (主備一致)

#!/bin/bash
LOGFILE=/var/log/keepalived-redis-status.log
echo "Running redis_stop.sh...." >>$LOGFILE
echo "[Stop]" >> $LOGFILE
date >> $LOGFILE
echo "Finished running redis_stop.sh...." >>$LOGFILE
5.5、給指令碼授可執行許可權

chmod +x /etc/keepalived/scripts_redis/*.sh

5.6、 keepalived相關命令

Keepalived 安裝命令

yum install keepalived -y

Keepalived配置所在目錄

/etc/keepalived

Keepalived 日誌檔案

/var/log/message

啟動Keepalived命令

systemctl start keepalived.service

重啟Keepalived命令

systemctl restart keepalived.service

檢視Keepalived狀態命令

systemctl status keepalived.service

檢視Keepalived虛擬VIP ip

ip addr

關閉Keepalived命令

systemctl stop keepalived.service

6、驗證主備雙活

我們可以透過連線工具RedisDesktopManager進行測試主備雙活。首先連線地址填寫keepalived生成的虛擬IP地址:192.168.42.161、 輸入埠號:6379和密碼:1234qwer

連線成功後,插入一條資料進行資料測試。之後在把主伺服器redis停止模擬伺服器當機,測試連線繼續進行資料插入。然後在把主伺服器redis啟動,keepalived也需要啟動。啟動完成後檢視資料是否一致。如果一致說明主備雙活搭建成功。

相關文章