先了解一下哨兵都 做了什么工作:Redis 的 Sentinel 系統用於管理多個 Redis 服務器(instance), 該系統執行以下三個任務:
- 監控(Monitoring): Sentinel 會不斷地檢查你的主服務器和從服務器是否運作正常。
- 提醒(Notification): 當被監控的某個 Redis 服務器出現問題時, Sentinel 可以通過 API 向管理員或者其他應用程序發送通知。
- 自動故障遷移(Automatic failover): 當一個主服務器不能正常工作時, Sentinel 會開始一次自動故障遷移操作, 它會將失效主服務器的其中一個從服務器升級為新的主服務器, 並讓失效主服務器的其他從服務器改為復制新的主服務器; 當客戶端試圖連接失效的主服務器時, 集群也會向客戶端返回新主服務器的地址, 使得集群可以使用新主服務器代替失效服務器。
Redis Sentinel 是一個分布式系統, 你可以在一個架構中運行多個 Sentinel 進程(progress), 這些進程使用流言協議(gossip protocols)來接收關於主服務器是否下線的信息, 並使用投票協議(agreement protocols)來決定是否執行自動故障遷移, 以及選擇哪個從服務器作為新的主服務器。
Redis Sentinel (哨兵)存在一個單獨的可執行文件 redis-sentinel , 但實際上它只是一個運行在特殊模式下的 Redis 服務器,通過Redis的哨兵去監控一個redis的集群,如果集群出現故障則自動進行故障遷移。
對於Redis Sentinel有兩種啟動方式,如下:
對於 redis-sentinel 程序, 你可以用以下命令來啟動 Sentinel 系統:
redis-sentinel /path/to/sentinel.conf
對於 redis-server 程序, 你可以用以下命令來啟動一個運行在 Sentinel 模式下的 Redis 服務器:
redis-server /path/to/sentinel.conf --sentinel
本例中實現的架構為三個redis,三個sentinel
| 節點 | IP | 端口 |
| redis1 | 127.0.0.1 | 7000(master) |
| redis2 | 127.0.0.1 | 7001(slave) |
| redis3 | 127.0.0.1 | 7001(slave) |
| redis-sentinel1 | 127.0.0.1 | 26379 |
| redis-sentinel2 | 127.0.0.1 | 26380 |
| redis-sentinel3 | 127.0.0.1 | 26381 |
一、配置redis集群
1.配置開啟主從節點
主節點:新建redis-7000.conf
配置:
port 7000
daemonize yes
pidfile /var/run/redis-7000.pid
logfile "7000.log"
dir "/root/redis/data"
啟動:redis-server redis-7000.conf
從節點:新建redis-7001.conf 和redis-7002.conf 文件
slave1配置:
port 7001
daemonize yes
pidfile /var/run/redis-7001.pid
logfile "7001.log"
dir "/root/redis/data"
slaveof 127.0.0.1 7000
slave2配置:
port 7002
daemonize yes
pidfile /var/run/redis-7002.pid
logfile "7002.log"
dir "/root/redis/data"
slaveof 127.0.0.1 7000
啟動:redis-server redis-7001.conf
redis-server redis-7002.conf
驗證redis集群:登錄redis1后info replication,其角色為master

登錄redis2后info replication,發現角色role:slave,其主master_host:127.0.0.1,master_port:7000

redis3的情況與redis2的情況是一樣的,可以在redis1中進行數據的增加,然后在節點2、3中查看是否同步成功,節點2、3只能進行讀操作,沒有寫的權限等操作驗證集群的正確性。
二、配置開啟sentinel監控主節點(sentinel 是特殊的redis)
1.配置三個sentinel節點
新建三個配置文件:redis-sentinel-26379.conf、redis-sentinel-26380.conf、redis-sentinel-26381.conf
port 26379
daemonize yes
dir "/root/redis/data"
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
port 26380
daemonize yes
dir "/root/redis/data"
logfile "26380.log"
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
port 26381
daemonize yes
dir "/root/redis/data"
logfile "26381.log"
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
分別按上面的方式啟動三個哨兵:redis-sentinel redis-sentinel-26379.conf
redis-sentinel redis-sentinel-26380.conf
redis-sentinel redis-sentinel-26381.conf
檢查三個哨兵是否啟動成功:

三個哨兵啟動成功以后,可以像登錄redis那樣登錄哨兵,但是哨兵有他自己的API,許多像數據的增加等命令哨兵是不認的。然后我們登錄任一一個進去使用info查看一下每個哨兵的信息,從下圖中可以看到master的信息以及slaves和sentinel的數量。

那么有一個問題,我們啟動 哨兵的時候並沒有配置redis的slave節點和其他sentinel節點,哨兵是怎么發現slave和其他sentinel的呢?其實是通過內部的一個發布訂閱消息來實現的,我們來看一下官方的解釋:
自動發現 Sentinel 和從服務器
一個 Sentinel 可以與其他多個 Sentinel 進行連接, 各個 Sentinel 之間可以互相檢查對方的可用性, 並進行信息交換。
你無須為運行的每個 Sentinel 分別設置其他 Sentinel 的地址, 因為 Sentinel 可以通過發布與訂閱功能來自動發現正在監視相同主服務器的其他 Sentinel , 這一功能是通過向頻道 sentinel:hello 發送信息來實現的。
與此類似, 你也不必手動列出主服務器屬下的所有從服務器, 因為 Sentinel 可以通過詢問主服務器來獲得所有從服務器的信息。
- 每個 Sentinel 會以每兩秒一次的頻率, 通過發布與訂閱功能, 向被它監視的所有主服務器和從服務器的 sentinel:hello 頻道發送一條信息, 信息中包含了 Sentinel 的 IP 地址、端口號和運行 ID (runid)。
- 每個 Sentinel 都訂閱了被它監視的所有主服務器和從服務器的 sentinel:hello 頻道, 查找之前未出現過的 sentinel (looking for unknown sentinels)。 當一個 Sentinel 發現一個新的 Sentinel 時, 它會將新的 Sentinel 添加到一個列表中, 這個列表保存了 Sentinel 已知的, 監視同一個主服務器的所有其他 Sentinel 。
- Sentinel 發送的信息中還包括完整的主服務器當前配置(configuration)。 如果一個 Sentinel 包含的主服務器配置比另一個 Sentinel 發送的配置要舊, 那么這個 Sentinel 會立即升級到新配置上。
- 在將一個新 Sentinel 添加到監視主服務器的列表上面之前, Sentinel 會先檢查列表中是否已經包含了和要添加的 Sentinel 擁有相同運行 ID 或者相同地址(包括 IP 地址和端口號)的 Sentinel , 如果是的話, Sentinel 會先移除列表中已有的那些擁有相同運行 ID 或者相同地址的 Sentinel , 然后再添加新 Sentinel 。
當我們的 哨兵啟動完成后自動將redis的slave節點和其他的哨兵節點的信息寫入到其配置文件中,也就是哨兵的配置文件發生了變化,在本例中內容如下:
port 26380
daemonize yes
dir "/root/redis/data"
logfile "26380.log"
sentinel myid 60ee52fc339d6713cf01429295333abc52af4c6b
sentinel monitor mymaster 127.0.0.1 7000 2
sentinel config-epoch mymaster 0
sentinel leader-epoch mymaster 0
# Generated by CONFIG REWRITE
sentinel known-slave mymaster 127.0.0.1 7001
sentinel known-slave mymaster 127.0.0.1 7002
sentinel known-sentinel mymaster 127.0.0.1 26381 06f16eb142ee0895dedd769d2d5072c7d682cc50
sentinel known-sentinel mymaster 127.0.0.1 26379 b0f4c698b611b92fb406f3a04815b0536baed055
sentinel current-epoch 0
至此我們的Redis的哨兵模式就搭建完成了,進行一下驗證,kill 7000端口的redis,觀察一下哨兵的自動故障轉移是否能成功。

master 變為了端口號為7001的redis,功能可以正常使用,這樣哨兵替我們完成了redis集群的故障的自動轉移。
