一 概述
哨兵模式是一主多從的模式,我這裏使用的是一主二從的模式,當主節點發生故障下線之後,哨兵就會從新選舉一個從節點來當主節點。
一. 準備
0> redis鏡像準備
docker pull redis:4.0.14-buster
1> 目錄準備
在linux系統下創建這樣的目錄:
/home/docker/redis/sentienl/redis
/home/docker/redis/sentienl/sentinel
2> 準備配置文件redis.conf
因爲是一主二從,所以redis.conf要準備三份。
- 在/home/docker/redis/sentienl/redis/16379 下放:
# 使得Redis服務器可以跨網絡訪問
bind 0.0.0.0
# 日誌文件
logfile "redis.log"
# 當前服務端口
port 16379
# 數據文件所在文件夾
dir "/data"
# 硬盤數據文件文件名
dbfilename "dump.rdb"
# 開啓AOF模式
appendonly yes
# 保存數據的AOF文件名稱
appendfilename "appendonly.aof"
# 從服務器密碼
masterauth "wszgr"
# 主服務器密碼,注意:有關slaveof的配置只是配置從服務器,主服務器不需要配置
requirepass "wszgr"
- 在/home/docker/redis/sentienl/redis/16380 下放:
# 使得Redis服務器可以跨網絡訪問
bind 0.0.0.0
# 日誌文件
logfile "redis.log"
# 當前服務端口
port 16380
# 數據文件所在文件夾
dir "/data"
# 硬盤數據文件文件名
dbfilename "dump.rdb"
# 開啓AOF模式
appendonly yes
# 保存數據的AOF文件名稱
appendfilename "appendonly.aof"
# 從服務器密碼
masterauth "wszgr"
# 主服務器密碼,注意:有關slaveof的配置只是配置從服務器,主服務器不需要配置
requirepass "wszgr"
# 做爲從服務連接主服務器
slaveof 192.168.47.150 16379
- 在/home/docker/redis/sentienl/redis/16380 下放:
# 使得Redis服務器可以跨網絡訪問
bind 0.0.0.0
# 日誌文件
logfile "redis.log"
# 當前服務端口
port 16381
# 數據文件所在文件夾
dir "/data"
# 硬盤數據文件文件名
dbfilename "dump.rdb"
# 開啓AOF模式
appendonly yes
# 保存數據的AOF文件名稱
appendfilename "appendonly.aof"
# 從服務器密碼
masterauth "wszgr"
# 主服務器密碼,注意:有關slaveof的配置只是配置從服務器,主服務器不需要配置
requirepass "wszgr"
# 做爲從服務連接主服務器
slaveof 192.168.47.150 16379
我這裏默認16379是啓動時候的主服務。
3> 準備sentinel.conf
哨兵的配置文件也是要準備三份的。
- 在/home/docker/redis/sentienl/sentinel/26379下放:
# 當前端口
port 26379
# 數據文件所在文件夾
dir "/data"
# 日誌文件
logfile "sentinel.log"
# 設置master和slaves驗證密碼
sentinel deny-scripts-reconfig yes
# 哨兵監聽的主服務器(配置的時候,後期主服務掛掉,自動尋找另外主服務)
#行尾最後的一個2代表什麼意思呢?我們知道,網絡是不可靠的,有時候一個sentinel會因爲網絡堵塞而誤以爲一個master redis已經死掉了,當sentinel集羣式,解決這個問題的方法就變得很簡單,只需要多個sentinel互相溝通來確認某個master是否真的死了,這個2代表,當集羣中有2個sentinel認爲master死了時,才能真正認爲該master已經不可用了。
sentinel monitor mymaster 192.168.47.150 16379 2
# 30s內mymaster無響應,則認爲mymaster宕機了
sentinel down-after-milliseconds mymaster 30000
# 指定了在執行故障轉移時, 最多可以有多少個從服務器同時對新的主服務器進行同步
sentinel parallel-syncs mymaster 1
# 若哨兵在配置值內未能完成故障轉移操作,則任務本次故障轉移失敗
sentinel failover-timeout mymaster 180000
# 定義服務的密碼,mymaster是服務名稱,wszgr是Redis服務器密碼
sentinel auth-pass mymaster wszgr
- 在/home/docker/redis/sentienl/sentinel/26380下放:
將上面的配置文件port改爲26380
- 在/home/docker/redis/sentienl/sentinel/26381下放:
將上面的配置文件port改爲26381
4> 準備redis-compose.yml 文件
version: '3'
services:
redis-16379:
image: redis:4.0.14-buster
container_name: redis-16379
command: redis-server redis.conf
restart: always
ports:
- "16379:16379"
volumes:
- ./redis/16379:/data
redis-16380:
image: redis:4.0.14-buster
container_name: redis-16380
command: redis-server redis.conf
restart: always
ports:
- "16380:16380"
volumes:
- ./redis/16380:/data
depends_on:
- redis-16379
redis-16381:
image: redis:4.0.14-buster
container_name: redis-16381
command: redis-server redis.conf
restart: always
ports:
- "16381:16381"
volumes:
- ./redis/16381:/data
depends_on:
- redis-16379
sentinel-26379:
image: redis:4.0.14-buster
container_name: sentinel-26379
command: redis-sentinel sentinel.conf
restart: always
ports:
- "26379:26379"
volumes:
- ./sentinel/26379:/data
depends_on:
- redis-16379
sentinel-26380:
image: redis:4.0.14-buster
container_name: sentinel-26380
command: redis-sentinel sentinel.conf
restart: always
ports:
- "26380:26380"
volumes:
- ./sentinel/26380:/data
depends_on:
- redis-16379
sentinel-26381:
image: redis:4.0.14-buster
container_name: sentinel-26381
command: redis-sentinel sentinel.conf
restart: always
ports:
- "26381:26381"
volumes:
- ./sentinel/26381:/data
depends_on:
- redis-16379
三. 啓動
進入到/home/docker/redis/sentienl目錄下執行以下命令:
docker-compose -f redis-compose.yml up -d
然後就可以進行測試了。
四. 隱性問題說明
由於我這裏採用的是docker的bridge方式,所以就存在一個網絡連接問題,雖然看起來我使用了端口映射,並且連接了映射到主機的端口,但是依然存在這樣的一個問題:
當主節點故障,哨兵就會切換一個從節點爲主節點,但是從節點返回給哨兵的連接地址卻是docker容器的地址,而不是宿主機的地址。那麼如果我們不是在一臺主機上部署測試,那麼連接就已經出現問題了(另一臺主機在沒有專門處理的情況下是無法連接到這臺主機的docker容器的。)。
所以如果你可以跨主機容器互聯也是可以的,或者採用網絡模式爲host模式(bridge模式不行),這樣直接使用宿主機的網絡也可以。當然不選用docker的方式,而是直接啓動redis只需要前面的redis和sentinel配置就可以了。