`前言`
Redis中的主從復制模式實現了讀寫分離,以及斷線重連之后的數據一致性,但是并沒有解決主機宕機時候出現的故障問題,Redis中使用哨兵模式來解決主機宕機問題。
## 哨兵模式
哨兵(sentinel)是一種運行在特殊模式下的Redis服務器,是Redis實現高可用的方案。由一個或者多個哨兵組成的哨兵系統可以用來監控一個或者多個主服務器,以及該主服務器下的所有從服務器。哨兵模式Redis服務器結構舉例:
:-: 
**哨兵系統的主要作用是在主服務器宕機時進行故障排查,根據一定策略將從服務器指定為新的主服務器**。
```
備注:哨兵模式的之所以說是特殊的Redis服務器是因為哨兵模式的代碼定義在sentinel.c,
并且定義了與redis.c中不同的命令支持。哨兵服務器只支持如下命令:
ping sentinel subscribe unsubscribe psubscribe punsubscribe publish info role
client shutdown auth hello acl command
```
## 啟動哨兵模式
1. 創建sentiel.conf,并配置監視主機對象
```bash
# 設置要監控的主機,最后面的 1 是表示有多少臺哨兵服務器認為該主機已經下線了就會啟動故障恢復功能
sentinel monitor master1 127.0.0.1 6379 1
# 設置實例為10秒內無響應則被判斷為主觀下線
sentinel down-after-milliseconds master1 10000
# 在進行故障恢復操作時,可以同時對新的主服務器進行同步的從服務器的數量
sentinel parallel-syncs master1 1
# 刷新故障遷移狀態的最大時限
sentinel failover-timeout master1 50000
```
主要配置:`sentinel monitor master_name ip port quorum`
其中quorum屬性為判斷主機為`客觀下線`所需要的哨兵服務器的投票數量,即有quorum臺哨兵已經認為它是`主觀下線`了,就會將該主機判斷為`客觀下線`,接著進行故障恢復操作。
2. 啟動哨兵服務器
如果有redis-sentinel的話可以直接使用命令
```bash
redis-sentinel sentinel.conf
```
如果沒有的話可以使用命令
```bash
redis-server sentinel.conf --sentinel
```

哨兵的默認端口為`26379`
## 宕機檢測機制
1. 檢測**主觀下線**狀態
哨兵服務器會每秒一次的向主服務器、從服務器、其他哨兵發送ping命令,用來判斷主服務器是否在線。在屬性`down-after-milliseconds`設置的秒數內沒有回應就會判斷成`主觀下線`。
2. 檢測**客觀下線**狀態
當哨兵服務器檢測到主服務器為主觀下線狀態,如果有其他哨兵服務器,則會像其他哨兵服務器發送信號詢問`你是否也任務該主服務器已經主觀下線了`。當同意(投票)數大于等于quorum設置的值,則會認為該主服務器真的宕機了,接著進行故障恢復。
例如在sentinel.conf中配置
```bash
sentinel monitor master1 127.0.0.1 6379 1
```
則當有一臺哨兵服務器認為該服務器master1主觀下線時就會進行故障恢復。
當配置
```bash
sentinel monitor master2 127.0.0.1 6380 5
```
則當有5臺哨兵服務器認為master2主觀下線時就會判斷為客觀下線,進行故障恢復操作。
## 故障轉移
當主服務器master1被認定為客觀下線時,領頭的哨兵(在有多個哨兵的系統中會通過一定策略選取一臺哨兵作為領頭的哨兵進行故障恢復操作)會逐步進行如下操作,以下圖的哨兵模式結構所示:
:-: 
1. 在以下線的主服務器的從服務器中挑選出一臺從服務器作為新的主服務器,選取的策略如下:
1. 不選處于斷線、下線、最近5秒內沒有回復哨兵的info命令的從服務器,同時不選與已下線的主服務連接斷開超過**down-after-milliseconds * 10**的從服務器。
2. 接著選擇優先級高的從服務器,從服務器的優先級在`slave-priority`或者(`replica-priority`不同版本不一樣)屬性中進行配置。

3. 優先級一樣則選擇復制偏移量replication_offset大的從服務器。
4. 復制偏移量一樣則根據從服務器runid進行字典序排序,選擇最小的runid。假設最終選擇了slave1
*復制偏移量和從服務器runid詳細可以看:
<a href="https://blog.csdn.net/weixin_44184990/article/details/117389980">《Redis主從復制》</a>*
5. 選擇完畢之后,哨兵會向選擇slave1服務器發送`slave no one`命令,將其提升為主服務器。
2 得到了新的主服務器之后,需要讓master1中的其他從服務器都成為slave1的從服務器,這只需要向每臺從服務器發送`slaveof ip port`即可。(*slaveof的詳細過程可以看:<a href="https://blog.csdn.net/weixin_44184990/article/details/117389980"></a>《Redis主從復制》*)
3. 當master1重新上線時,需要將master1設置成slave1的從服務器。
按照示例最終哨兵模式結構如下:
:-: 
通過上述故障恢復策略會選擇一個數據保留比較完整的從服務作為主服務器,這個過程是在哨兵的監視下自動完成的,也就實現了在主服務器宕機下的Redis系統的高可用性。
【參考】
1. 《Redis設計與實現》第16章
- 第一章 Java基礎
- ThreadLocal
- Java異常體系
- Java集合框架
- List接口及其實現類
- Queue接口及其實現類
- Set接口及其實現類
- Map接口及其實現類
- JDK1.8新特性
- Lambda表達式
- 常用函數式接口
- stream流
- 面試
- 第二章 Java虛擬機
- 第一節、運行時數據區
- 第二節、垃圾回收
- 第三節、類加載機制
- 第四節、類文件與字節碼指令
- 第五節、語法糖
- 第六節、運行期優化
- 面試常見問題
- 第三章 并發編程
- 第一節、Java中的線程
- 第二節、Java中的鎖
- 第三節、線程池
- 第四節、并發工具類
- AQS
- 第四章 網絡編程
- WebSocket協議
- Netty
- Netty入門
- Netty-自定義協議
- 面試題
- IO
- 網絡IO模型
- 第五章 操作系統
- IO
- 文件系統的相關概念
- Java幾種文件讀寫方式性能對比
- Socket
- 內存管理
- 進程、線程、協程
- IO模型的演化過程
- 第六章 計算機網絡
- 第七章 消息隊列
- RabbitMQ
- 第八章 開發框架
- Spring
- Spring事務
- Spring MVC
- Spring Boot
- Mybatis
- Mybatis-Plus
- Shiro
- 第九章 數據庫
- Mysql
- Mysql中的索引
- Mysql中的鎖
- 面試常見問題
- Mysql中的日志
- InnoDB存儲引擎
- 事務
- Redis
- redis的數據類型
- redis數據結構
- Redis主從復制
- 哨兵模式
- 面試題
- Spring Boot整合Lettuce+Redisson實現布隆過濾器
- 集群
- Redis網絡IO模型
- 第十章 設計模式
- 設計模式-七大原則
- 設計模式-單例模式
- 設計模式-備忘錄模式
- 設計模式-原型模式
- 設計模式-責任鏈模式
- 設計模式-過濾模式
- 設計模式-觀察者模式
- 設計模式-工廠方法模式
- 設計模式-抽象工廠模式
- 設計模式-代理模式
- 第十一章 后端開發常用工具、庫
- Docker
- Docker安裝Mysql
- 第十二章 中間件
- ZooKeeper