Redis部署手記之哨兵模式

一、哨兵模式
1.1簡介
前面所配置的主從模式,雖然實現了讀寫分離,解決了數據備份問題和單機模式可能存在的性能問題,但是也引入了新的問題:
由於主從模式下可以將讀寫操作分配給不同的 Redis 節點,從而達到提高系統吞吐量的目的,但也正是因爲這種方式造成了使用上的不便。因爲客戶端連接到不同的 Redis 節點時,都需要指定特定的 IP 端口,若所連接的節點因爲故障下線了,主從模式便無法通知客戶端切換到另一個可用節點,只能靠手動更改客戶端配置並重連。
尤其是如果故障下線的是主節點,那麼所有的從節點便會因爲沒有主節點而同步中斷,整個集羣會陷入癱瘓(嚴格來說是所有從節點變成獨立節點,再無關聯性),直至人工重新指定新的主節點。

爲了解決上面的問題,Redis 在 2.8 版本後開始支持哨兵模式,其架構模式如下圖:
在這裏插入圖片描述
當主節點掉線後,會進行如下的過程,會從從節點中產生一個主節點,代替原來的主節點:
在這裏插入圖片描述
Redis 的Sentinel 系統(即哨兵系統)可用於管理多組 Redis 主從實例,它是Redis的高可用性解決方案。這個系統主要執行以下三個任務:

  • 監控(Monitoring):Sentinel 會不斷地定期檢查主/從節點服務器是否運作正常
  • 提醒(Notification):當被監控的某個節點服務器出現問題時,Sentinel 可以通過 API 向管理員或者其他應用程序發送通知
  • 自動故障遷移(Automaticfailover):當一個主節點不能正常工作時,Sentinel 會開始一次自動故障遷移操作,它會將失效主節點下的其中一個從節點升級爲新的主節點,並讓失效主節點的其他從節點改爲複製新的主節點。當 Redis 客戶端試圖連接失效的主節點時,集羣也會向客戶端返回新主節點的地址,使得集羣可以使用新主節點代替失效主節點。

1.2部署
下面演示如何在上一階段的主從模式基礎上,增加部署一套哨兵系統。
先準備好三份配置文件:

角色 配置文件 監聽端口
哨兵 sentinel-26380.conf 26380
哨兵 sentinel-26381.conf 26381
哨兵 sentinel-26382.conf 26382

注: 這三份配置文件均拷貝自/usr/local/redis-ms/sentinel.conf ,拷貝到 /usr/local/redis-ms/ 目錄再修即可。建議哨兵至少部署 3 個,並且哨兵節點數量要滿足 2n+1(n>=1),即奇數個。

哨兵 sentinel-26380.conf 配置文件內容如下:

bind 127.0.0.1                           # 正式部署請設爲合適的 IP
port 26380
daemonize yes                            # 後臺啓動模式(若無配置項則添加)
dir /tmp/redis-ms                        # Redis 的工作目錄(若不存在需手建否則無法啓動),logfile 受其影響
logfile "sentinel-26380.log"             # 哨兵日誌名稱(若無配置項則添加),正式部署請設置爲合適的名稱
sentinel monitor mymaster  127.0.0.1 6379 2     # 標註所監視的主機(其下的從機會被自動拉取,無需配置)
sentinel down-after-milliseconds mymaster  30000
sentinel parallel-syncs mymaster  1
sentinel failover-timeout mymaster  180000

哨兵 sentinel-26381.conf 配置文件內容如下:

bind 127.0.0.1                           # 正式部署請設爲合適的 IP
port 26381
daemonize yes                            # 後臺啓動模式(若無配置項則添加)
dir /tmp/redis-ms                        # Redis 的工作目錄(若不存在需手建否則無法啓動),logfile 受其影響
logfile "sentinel-26381.log"             # 哨兵日誌名稱(若無配置項則添加),正式部署請設置爲合適的名稱
sentinel monitor mymaster  127.0.0.1 6379 2        # 標註所監視的主機(其下的從機會被自動拉取,無需配置)
sentinel down-after-milliseconds exp-blog.com 30000
sentinel parallel-syncs mymaster  1
sentinel failover-timeout mymaster  180000

哨兵 sentinel-26382.conf 配置文件內容如下:

bind 127.0.0.1                   # 正式部署請設爲合適的 IP
port 26382                         
daemonize yes                    # 後臺啓動模式(若無配置項則添加)
dir /tmp/redis-ms                # Redis 的工作目錄(若不存在需手建否則無法啓動),logfile 受其影響
logfile "sentinel-26382.log"      # 哨兵日誌名稱(若無配置項則添加),正式部署請設置爲合適的名稱
sentinel monitor exp-blog.com 127.0.0.1 6379 2        # 標註所監視的主機(其下的從機會被自動拉取,無需配置)
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster  1
sentinel failover-timeout mymaster  180000

針對以上幾個sentinel-xxxxx.conf 配置中的幾個關鍵配置項說明如下:

sentinel monitor mymaster  127.0.0.1 6379 2
監控的主節點的名字爲mymaster(這個名字任意的,有效字符爲[A-Z] [a-z] [0-9] [._-])
監控的主節點服務地址 127.0.0.1:6379
行尾最後的 2 表示當集羣中有 2 個以上 sentinel 認爲主節點下線時,才認爲其客觀下線

sentinel down-after-milliseconds mymaster 30000
主節點在 30000 ms 內無反應,哨兵會開始使用“選舉機制”進行主從切換

sentinel parallel-syncs mymaster 1
在因主節點失效而發生故障轉移(即主從切換)時,這個參數決定了最多可以有多少個從節點同時對新的主節點進行併發同步。這個數字越小,完成故障轉移所需的時間就越長(餘下的從節點需要排隊等待同步);但這個數字越大,就意味着越多的從節點因爲正在對新的主節點進行同步而不可用。當從節點只用於查詢服務時,可將此值設爲 1 確保最多隻有一個從節點因同步而不可用。

sentinel failover-timeout mymaster180000
如果在該 180000 ms 內未能完成故障轉移,則認這次故障轉移超時失敗。
不過即使超時,從節點也會正確指向新主節點,但不會按照 parallel-syncs 規則進行同步

接下來就可以啓動 Redis 主從服務和 Sentinel 系統了。
啓動順序必須嚴格按照:

Redis Master(主節點) -> Redis Slave(從節點) -> Redis Sentinel(哨兵節點)

主從服務的啓動在上一階段已經做過了,此處就不重啓了。
Sentinel 系統需要使用 redis-sentinel命令啓動:

cd /usr/local/redis-ms/src/         # 切換到啓動腳本目錄
./redis-sentinel ../sentinel-26380.conf       # 啓動 Redis 哨兵節點
./redis-sentinel ../sentinel-26381.conf       # 啓動 Redis 哨兵節點
./redis-sentinel ../sentinel-26382.conf       # 啓動 Redis 哨兵節點

1.3 測試
現在測試 Sentinel 系統是否能正常工作。
可先通過ps -ef|grep redis 命令可查看四個主從進程和三個監控進程是否正常啓動:
在這裏插入圖片描述
然後通過 Redis 測試客戶端命令 redis-cli 連接到任意一臺 Sentinel 機器查看監控信息(實際生
產環境中,一般是不需要連接 Sentinel 機器的):

cd /usr/local/redis-ms/src/             # 切換到啓動腳本目錄
./redis-cli -h 127.0.0.1 -p 26380       # 連接到哨兵機 26380
127.0.0.1:26380> info sentinel          # 查看監控信息


./redis-cli -h 127.0.0.1 -p 26381
127.0.0.1:26381> info sentinel


./redis-cli -h 127.0.0.1 -p 26382
127.0.0.1:26382> info sentinel


# 三臺哨兵的返回信息是一致的:
# Sentinel
sentinel_masters:1            #監控一臺主機
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=3,sentinels=3
# 0 號主機名稱爲mymaster,地址爲 127.0.0.1:6379,共有三臺從機,三臺哨兵機

現在嘗試終止 Redis 主機進程(6379 端口節點)來模擬主機下線:

cd /usr/local/redis-ms/src/       # 切換到啓動腳本目錄
./redis-cli -h 127.0.0.1 -p 6379    # 連接到 Redis 主機
127.0.0.1:6379> shutdown      # 終止 Redis 服務

然後連接到任意一臺哨兵機,查看當前的監控信息:

cd /usr/local/redis-ms/src/         # 切換到啓動腳本目錄
./redis-cli -h 127.0.0.1 -p 26380     # 連接到哨兵機 26380
127.0.0.1:26380> info sentinel       # 查看監控信息
 
# 返回監控信息
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6382,slaves=3,sentinels=3     # 主機地址發生變化了

不難發現主機變成了 127.0.0.1:6382,登陸這臺主機查看主從信息:

cd /usr/local/redis-ms/src/         # 切換到啓動腳本目錄
./redis-cli -h 127.0.0.1 -p 6382     # 連接到 Redis 主機
127.0.0.1:6382> info replication     # 查看主從信息

# 返回主從信息
# Replication
role:master            #角色是主節點
connected_slaves:2     #其下有兩個從節點
slave0:ip=127.0.0.1,port=6380,state=online,offset=106257,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=106124,lag=0
master_replid:199f376adf11c411e84584a320cd825fd48fd60e
master_replid2:e042fa1900358b32eaa4b84817642e04145c9c87
master_repl_offset:106523
second_repl_offset:88686
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:106523

由此可知,當原主機 6379 下線後,原從機 6382 被哨兵系統提升爲新的主機,而其他的兩臺從機 6380 和 6381 變成新主機 6382 的從機。此時集羣系統變成一主兩從。

現在重新啓動 6379 機器:

cd /usr/local/redis-ms/src/       # 切換到啓動腳本目錄
./redis-server ../redis-6379.conf     # 啓動 Redis 機器

再登陸新主機 127.0.0.1:6382 查看主從信息:

cd /usr/local/redis-ms/src/         # 切換到啓動腳本目錄
./redis-cli -h 127.0.0.1 -p 6382     # 連接到 Redis 主機
127.0.0.1:6382> info replication     # 查看主從信息

# 返回主從信息
# Replication
role:master      #6382還是主節點
connected_slaves:3
slave0:ip=127.0.0.1,port=6380,state=online,offset=136282,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=136282,lag=1
slave2:ip=127.0.0.1,port=6379,state=online,offset=136282,lag=1    #重啓後的6379並沒有做回主節點,而是成爲6382的從節點
master_replid:199f376adf11c411e84584a320cd825fd48fd60e
master_replid2:e042fa1900358b32eaa4b84817642e04145c9c87
master_repl_offset:136282
second_repl_offset:88686
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:136282

由此可知,當 6379 機器重新上線後,並不會恢復原主機的身份,而是被哨兵系統掛接到新主機 6382 下,成爲其從機。此時集羣系統重新變成一主三從。

至此 Redis 哨兵模式部署完成。
爲了下面部署Redis集羣,現在先停止前面部署的所有 Redis 進程:

#pkill redis

1.4哨兵模式一鍵啓動/停止/重啓腳本
此腳本是在本次實驗的部署方式和位置爲基礎編寫的,僅適用於 Redis 節點均在同一臺機器的場景。若要在其他地方使用,需要根據實際情況進行修改。

#!/bin/bash
# 根據主從/哨兵模式的部署目錄對應修改
cd /usr/local/redis-ms/src/

# 啓動函數
start()
 {
./redis-server ../redis-6379.conf	&
./redis-server ../redis-6380.conf	&
./redis-server ../redis-6381.conf	&
./redis-server ../redis-6382.conf	&
./redis-sentinel ../sentinel-26380.conf	&
./redis-sentinel ../sentinel-26381.conf	&
./redis-sentinel ../sentinel-26382.conf	&
echo "all running"
}

# 停止函數
stop()
{
ps -ef | grep "redis" | grep -v "grep" |awk '{print $2}'| while read pid
do
C_PID=$(ps --no-heading $pid | wc -l)
if [[ $C_PID == "1" ]]; then
kill -9 $pid
echo "PID=$pid is dead"
else
echo "PID=$pid not exists"
fi
done
echo "all dead"
}

# 腳本入口參數 start|stop|restart
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
printf 'Usage: %s {start|stop|restart}\n'"$prog"
exit 1
;;
esac

這是 shell 腳本,保存爲mss.sh(文件名任意)即可執行(若無法執行可能是換行符問題,可嘗試通過 dos2unix 命令修正換行符)。

sh mss.sh start    # 啓動
sh mss.sh stop     # 停止
sh mss.sh restart  # 重啓
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章