前言
繼上一篇 w4560000 - Redis Master-Slave 建置完 Redis Master-Slave 主從複製機制後,接著研究哨兵模式
在以往單體 Redis 服務異常當下,會需要維運人員手動介入處理
而若使用 Master-Slave 機制時,當 Master 發生異常,Redis 可透過 Sentinel (哨兵機制) 從 Slave 中選出一個來當 Master
環境
Linux VM = ubuntu-2004-lts
Redis Docker映像檔 = redis:6.0.0
Master、Slave 建置參考上一篇 w4560000 - Redis Master-Slave#環境
本篇接續建立 3 台 Redis Sentinel (哨兵機制),加上原有的 Master、Slave,共有 6 台
機器 | IP |
---|---|
redis-master | 10.140.0.20 |
redis-slave-1 | 10.140.0.21 |
redis-slave-2 | 10.140.0.22 |
redis-sentinel-1 | 10.140.0.11 |
redis-sentinel-2 | 10.140.0.12 |
redis-sentinel-3 | 10.140.0.13 |
設定 VM
建立 3 台 Sentinel 機器
for i in 1 2 3; do
gcloud compute instances create redis-sentinel-${i} \
--async \
--boot-disk-size 100GB \
--can-ip-forward \
--image-family ubuntu-2004-lts \
--image-project ubuntu-os-cloud \
--machine-type e2-standard-2 \
--private-network-ip 10.240.0.1${i} \
--scopes compute-rw,storage-ro,service-management,service-control,logging-write,monitoring \
--subnet redis-vpc-subnet \
--zone asia-east1-a \
--tags redis-vpc
done
安裝 Docker
參考 w4560000 - Linux 安裝 Docker、Docker-Compose
3 台 VM 都先設定好 volumn 資料夾
mkdir redis && mkdir redisdata
建置 Sentinel (哨兵機制)
設定 sentinel.conf
哨兵數量需為 2n +1 (n >= 1),需為奇數才能投票
sentinel monitor
設定要監控的 Master、最後的數字代表有幾個哨兵判斷 Master 異常,才算判定異常
建議設定 (哨兵數 / 2) +1
ex: sentinel monitor mymaster 10.240.0.20 6379 2sentinel down-after-milliseconds
判斷 Master 是否存活,預設是 30 秒,若超過時間則會被判定異常
ex: sentinel down-after-milliseconds mymaster 30000sentinel failover-timeout
故障轉移超時時間
ex: sentinel failover-timeout mymaster 180000parallel-syncs
故障轉移期間,允許多少個 Slave 同時向新的 Master 同步資料,預設是 1 個
ex: parallel-syncs mymaster 1
sentinel announce-ip
sentinel announce-port
暴露IP、Port
Redis 的 sentinel 會宣告自己的IP、Port,讓其他 sentinel 監聽
在 Docker 環境會因為容器內 IP,與主機 IP 不同,導致其他 semtinel 是監聽到容器內的 IP,而不是主機 IP
可透過這兩個參數來指定主機 IP、Port
ex: sentinel announce-ip 10.240.0.11
ex: sentinel announce-port 26379
參考 Redis 官方文件 - Sentinel, Docker, NAT, and possible issues
sentinel-1、sentinel-2、sentinel-3
路徑 ~/redis/sentinel.conf
分別建立 sentinel.conf
sentinel-1
port 26379
sentinel monitor mymaster 10.240.0.20 6379 2
sentinel down-after-milliseconds mymaster 1000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel announce-ip 10.240.0.11
sentinel announce-port 26379
sentinel-2
port 26379
sentinel monitor mymaster 10.240.0.20 6379 2
sentinel down-after-milliseconds mymaster 1000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel announce-ip 10.240.0.12
sentinel announce-port 26379
sentinel-3
port 26379
sentinel monitor mymaster 10.240.0.20 6379 2
sentinel down-after-milliseconds mymaster 1000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
sentinel announce-ip 10.240.0.13
sentinel announce-port 26379
設定 Master、Slave redis.conf 權限
Master、Slave 設定權限
sudo chmod 777 redis/redis.conf
當故障轉移時,Redis 會修改 redis.conf,所以需要設定權限
假設當 Master 異常時,轉移 Master 給 Slave2,而 Redis 就會自動修改 Master、Slave1、Slave2 的 Redis.conf
ex:
機器 | 修改前 | 修改後 |
---|---|---|
redis-master | replicaof 10.240.0.22 6379 | |
redis-slave-1 | replicaof 10.240.0.20 6379 | replicaof 10.240.0.22 6379 |
redis-slave-2 | replicaof 10.240.0.20 6379 |
設定 Sentinel sentinel.conf 權限
sudo chmod 777 redis/sentinel.conf
若沒有設定會出現異常 Sentinel config file /usr/local/etc/redis/sentinel.conf is not writable: Permission denied
啟動 Sentinel 服務
三台 Sentinel 建立 redis-sentinel
docker run --name redis-sentinel \
-p 26379:26379 \
-v /home/leozheng0411/redis:/usr/local/etc/redis \
-v /home/leozheng0411/redisdata:/data \
-d redis:6.0.0 \
redis-server /usr/local/etc/redis/sentinel.conf --sentinel
災難異常復原模擬
目前配置
機器 | IP |
---|---|
redis-master | 10.140.0.20 |
redis-slave-1 | 10.140.0.21 |
redis-slave-2 | 10.140.0.22 |
redis-sentinel-1 | 10.140.0.11 |
redis-sentinel-2 | 10.140.0.12 |
redis-sentinel-3 | 10.140.0.13 |
先確認服務是否建置成功
redis-master
docker exec -it redis-master redis-cli info replication
# 輸出
# Replication
role:master
connected_slaves:2
slave0:ip=10.240.0.21,port=6379,state=online,offset=19852,lag=1
slave1:ip=10.240.0.22,port=6379,state=online,offset=19852,lag=1
master_replid:97d66f61b367b1f49b5c9ff233a3722553d94f65
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:19852
master_repl_meaningful_offset:19838
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:19852
redis-sentinel-1
docker exec -it redis-sentinel redis-cli -p 26379 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=10.240.0.20:6379,slaves=2,sentinels=3
測試流程如下
- 停用 redis-master
redis-master
docker rm -f redis-master
- 確認 redis-sentinel 是否有操作故障轉移
redis-sentinel-1
docker logs redis-sentinel
# 輸出
1:X 20 Jun 2023 07:53:36.998 # +sdown master mymaster 10.240.0.20 6379
1:X 20 Jun 2023 07:53:37.054 # +odown master mymaster 10.240.0.20 6379 #quorum 3/2
1:X 20 Jun 2023 07:53:37.054 # +new-epoch 1
1:X 20 Jun 2023 07:53:37.054 # +try-failover master mymaster 10.240.0.20 6379
1:X 20 Jun 2023 07:53:37.082 # +vote-for-leader 761245a97aa658488cdc866cac6b23b6a8cc04ef 1
1:X 20 Jun 2023 07:53:37.083 # f48158aed0b646e2e8dda0091735ac072829d7ef voted for f48158aed0b646e2e8dda0091735ac072829d7ef 1
1:X 20 Jun 2023 07:53:37.120 # a0cb3eb2fe013e9d2c389af6bbd314dff671c874 voted for f48158aed0b646e2e8dda0091735ac072829d7ef 1
1:X 20 Jun 2023 07:53:38.076 # +config-update-from sentinel f48158aed0b646e2e8dda0091735ac072829d7ef 10.240.0.12 26379 @ mymaster 10.240.0.20 6379
1:X 20 Jun 2023 07:53:38.076 # +switch-master mymaster 10.240.0.20 6379 10.240.0.22 6379
1:X 20 Jun 2023 07:53:38.076 * +slave slave 10.240.0.21:6379 10.240.0.21 6379 @ mymaster 10.240.0.22 6379
1:X 20 Jun 2023 07:53:38.076 * +slave slave 10.240.0.20:6379 10.240.0.20 6379 @ mymaster 10.240.0.22 6379
Master 被轉移給 redis-slave-2 (10.240.0.22)
- 確認新 Master,更新資料後,是否會同步給另一個 Slave
redis-slave-1
docker exec -it redis-slave redis-cli get Key1
# 輸出
(nil)
redis-slave-2
docker exec -it redis-slave redis-cli set Key1 "1"
redis-slave-1
docker exec -it redis-slave redis-cli get Key1
# 輸出
"1"
redis-slave-2 (新 Master) 寫入資料後,會同步更新 redis-slave-1
- 重啟 redis-master,確認是否會同步新 Master 的資料,確保資料一致
redis-master
docker run --name redis-master \
-p 6379:6379 \
-v /home/leozheng0411/redis:/usr/local/etc/redis \
-v /home/leozheng0411/redisdata:/data \
-d redis:6.0.0 \
redis-server /usr/local/etc/redis/redis.conf
docker exec -it redis-master redis-cli get Key1
# 輸出
"1"
redis-master 重啟後,會被 Sentinel 在 redis.conf 新增 replicaof <新Master>
補充
sdown (主觀下線)
當 Redis Sentinel 依照 down-after-milliseconds 的設定,判斷 Master 沒回應時,會判定主觀下線 (+sdown)
此時會詢問其他 Sentinel 來判定,當其他 Sentinel +sdown 的票數達到 sentinel monitor 設定的 quorum 時,則會被判定成 +odown
odown (客端下線)
當其他 Sentinel +sdown 的票數達到 sentinel monitor 設定的 quorum 時,則會被判定成 +odown
當 Master 被判斷成 +odown,則開始啟動 failover 機制
若移除主觀下線、客端下線標記則為 -sdown 、 -odown
參考文件
HackMD tienyulin - Redis (六) - 主從複製、哨兵與叢集模式#哨兵模式
TPIU 吳建男 Lancelot Wu - Redis sentinel 簡介與部署
博客園 SlowTech - 深入理解Redis高可用方案-Sentinel
博客園 DBA’s Record - Redis Sentinel机制与用法说明【转】
轉載請註明來源,若有任何錯誤或表達不清楚的地方,歡迎在下方評論區留言,也可以來信至 leozheng0621@gmail.com
如果文章對您有幫助,歡迎斗內(donate),請我喝杯咖啡