Redis Sentinel 詳解
1. 什么是 Redis Sentinel?有什么用?
Redis Sentinel(哨兵) 是 Redis 官方提供的高可用性解決方案,主要用于監控、通知和自動故障轉移。當 Redis 主節點(master)發生故障時,Sentinel 能夠自動選舉新的 master,并通知客戶端以保證 Redis 集群的高可用性。
Redis Sentinel 主要提供以下功能:
- 監控(Monitoring): 定期檢查 Redis 主從(master-slave)實例的可用性。
- 通知(Notification): 當某個實例出現故障時,Sentinel 會向系統管理員或其他應用程序發送通知。
- 自動故障轉移(Automatic Failover): 發現主節點不可用后,自動從從節點(slave)中選舉新的 master,并讓其他 slave 重新復制新的 master。
- 配置管理(Configuration Provider): 客戶端可以連接 Sentinel,獲取當前可用的 Redis master 地址,減少手動維護的復雜度。
2. Sentinel 如何檢測節點是否下線?
Sentinel 通過定期發送 PING 命令檢測 Redis 節點的狀態:
- 如果某個 Redis 節點長時間沒有響應 PING(超時),Sentinel 認為它可能下線,并標記為主觀下線(Subjectively Down,簡稱 SDOWN)。
- 如果多個 Sentinel 對該節點都判斷為主觀下線,并且達成一致意見,Sentinel 便標記其為客觀下線(Objectively Down,簡稱 ODOWN),然后進行故障轉移。
檢測機制
Sentinel 通過 sentinel.conf
配置文件中的 down-after-milliseconds
參數設置超時時間。例如:
sentinel down-after-milliseconds mymaster 5000
表示 Sentinel 如果 5 秒內未收到 PONG 響應,就認為該節點主觀下線(SDOWN)。
3. 主觀下線(SDOWN)與客觀下線(ODOWN)的區別
- 主觀下線(SDOWN,Subjectively Down)
- 單個 Sentinel 認為某個 Redis 節點不可用,僅基于自己 PING 的響應情況得出結論。
- 由于網絡問題,可能是 Sentinel 誤判,因此不會立即觸發故障轉移。
- 客觀下線(ODOWN,Objectively Down)
- 需要多個 Sentinel 經過投票一致認為某個 Redis 節點確實不可用,才會標記其為 ODOWN。
- 只有當 Sentinel 認定 master 為 ODOWN 后,才會觸發故障轉移。
4. Sentinel 是如何實現故障轉移的?
當 Sentinel 發現 Redis 主節點 ODOWN 后,故障轉移(failover)流程如下:
- 選舉新的 master
- Sentinel 選出一個可用的 slave 作為新的 master。
- 其他 slave 重新配置,開始同步新的 master。
- 更新 Sentinel 配置
- Sentinel 更新集群配置,并通知其他 Sentinel、客戶端新的 master 地址。
- 通知客戶端
- 客戶端可以從 Sentinel 處獲取新的 master 地址,繼續正常工作。
5. 為什么建議部署多個 Sentinel 節點(哨兵集群)?
部署多個 Sentinel 主要是為了提高可靠性,避免單點故障,并增強故障轉移的準確性:
- 避免單點故障:單個 Sentinel 可能宕機,導致無法監測 Redis 狀態,因此需要多個 Sentinel 互相監控。
- 提高判斷準確性:多個 Sentinel 通過投票機制決定 master 是否真的 ODOWN,避免誤判(如網絡抖動)。
- 支持故障轉移:Sentinel 需要多個節點達成共識后才能執行 failover,以保證一致性。
一般建議至少部署 3 個 Sentinel,以保證投票機制能夠生效。
6. Sentinel 如何選擇出新的 master(選舉機制)?
當 Redis master 被判定 ODOWN 后,Sentinel 需要從 slave 里選出新的 master,遵循以下原則:
- 優先級(Priority):優先選擇
slave-priority
值最低的從節點(值越小,優先級越高)。 - 復制進度(Replication Offset):如果多個 slave 的優先級相同,則選擇數據同步最完整(復制偏移量最大的)slave。
- 運行時長(Run ID):如果前兩個條件仍然無法區分,Sentinel 選擇
runid
字典序最小的 slave。 - 可用性:確保 slave 可用,并且能夠成功被轉換為 master。
一旦選出新的 master,Sentinel 會執行 SLAVEOF NO ONE
命令,將其轉換為 master,并讓其他 slave 重新同步該 master。
7. 如何從 Sentinel 集群中選擇出 Leader?
當多個 Sentinel 發現 master ODOWN 后,需要選舉一個 Sentinel 作為Leader,負責執行故障轉移。Leader 選舉流程如下:
- Sentinel 通過 Raft 算法類似的 Leader 選舉機制 進行投票:
- 每個 Sentinel 都可以提議自己為 Leader。
- 其他 Sentinel 如果尚未投票,可能會投票給它。
- 如果某個 Sentinel 獲得超過一半的投票,它就被選為 Leader。
- Leader 負責執行故障轉移
- 選舉出新的 master,并通知其他 Sentinel 進行更新。
如果 Leader 在 failover 過程中宕機,其他 Sentinel 會重新選舉新的 Leader,繼續執行 failover。
8. Sentinel 可以防止腦裂(Split-Brain)嗎?
部分情況下,Sentinel 機制可以緩解腦裂問題,但無法完全避免。例如:
- 避免單機多主(Multiple Masters)
- Sentinel 通過投票機制,確保只有一個 master 存在,防止多個 Sentinel 誤判后產生多個 master。
- 可能的腦裂場景
- 如果 master 因網絡分區短暫失聯,Sentinel 可能會選出新的 master,但原 master 仍在運行,導致出現兩個 master(腦裂)。
- 解決方案:
- 采用
min-slaves-to-write
和min-slaves-max-lag
配置,確保 master 只有在足夠多 slave 連接時才允許寫入。 - 使用 Redis Cluster,避免 Sentinel 方案中的潛在腦裂問題。
- 采用
總結
問題 | 關鍵點 |
---|---|
Sentinel 作用 | 監控 Redis 狀態,通知變更,執行故障轉移 |
主觀下線 vs 客觀下線 | SDOWN 由單個 Sentinel 認定,ODOWN 需要多個 Sentinel 認定 |
故障轉移流程 | 發現 ODOWN → 選出新的 master → 更新配置并通知客戶端 |
Sentinel 集群優勢 | 避免單點故障,提高可靠性,確保故障轉移準確性 |
新 master 選舉機制 | 按 slave-priority 、復制進度、運行時間長短等進行篩選 |
Sentinel Leader 選舉 | 采用 Raft 類似算法,得票最多的 Sentinel 負責 failover |
是否防止腦裂 | 只能緩解,不能完全避免,推薦 Redis Cluster 方案 |
如果你的 Redis 需要高可用性,Sentinel 是一個不錯的選擇,但要謹慎處理腦裂問題和網絡分區情況。
拓展閱讀
1. 什么是網絡分區(Network Partition)?
網絡分區(Network Partition) 指的是 由于網絡故障,導致集群中部分節點之間無法通信。網絡分區不會直接讓節點宕機,而是讓它們變成孤立的“孤島”,互相無法感知對方的狀態。
在 Redis Sentinel 方案中,網絡分區可能導致:
- Sentinel 誤判 master 失聯,觸發故障轉移(但原 master 仍然運行)。
- 多個 Sentinel 彼此之間無法溝通,導致 split-brain(腦裂)問題。
2. 什么是腦裂(Split-Brain)?
腦裂(Split-Brain) 指的是由于網絡分區,導致多個 master 節點并存,這會引發數據不一致、數據丟失等嚴重問題。
場景示例:
- 網絡分區發生:
- Redis 主節點(master)與大部分 Sentinel 失去聯系(但仍然存活)。
- 這時,Sentinel 誤認為 master 已宕機,觸發故障轉移,選舉新的 master。
- 原 master 繼續提供服務:
- 由于原 master 仍然存活,客戶端可能仍然在寫入它的數據,而新的 master 也在接受寫入。
- 這樣,就會產生兩個 master,各自接受不同的數據。
- 網絡恢復后:
- 原 master 重新連接 Sentinel,但 Sentinel 發現新的 master 已經存在。
- 由于兩個 master 的數據不同,Redis 無法自動合并數據,可能導致部分數據丟失。
3. 腦裂發生后如何解決?
腦裂發生后,通常需要手動干預來恢復一致性。常見的解決方案包括:
方法 1:配置 slave 強制下線(min-slaves-to-write & min-slaves-max-lag)
在 Redis 主從架構中,可以通過 min-slaves-to-write
和 min-slaves-max-lag
參數確保 master 只在有足夠 slave 存活時才允許寫入:
min-slaves-to-write 1
min-slaves-max-lag 10
- 作用:如果 master 發現自己沒有足夠的 slave,或者 slave 的同步滯后超過 10 秒,它就會拒絕寫入。
- 效果:如果 master 因網絡分區變成孤立節點,它將自動進入只讀模式,避免腦裂。
方法 2:手動干預
如果腦裂已經發生,可以執行以下步驟:
-
檢測當前集群狀態
- 運行
INFO replication
查看 master 和 slave 角色。 - 運行
SENTINEL master <master-name>
檢查 Sentinel 認為的 master 是誰。
- 運行
-
強制廢棄舊 master
-
如果原 master 變成了孤立的 master(split-brain 發生),可以執行:
redis-cli -h old-master -p 6379 SLAVEOF new-master-host new-master-port
-
這樣,原 master 重新作為 slave,從新 master 同步數據。
-
方法 3:使用 Redis Cluster
Redis Sentinel 主要解決的是“高可用性”問題,但無法徹底解決腦裂問題。
Redis Cluster 采用了Gossip 協議和數據分片機制,能夠更好地防止腦裂:
- 多數派寫入(Quorum Writes):只有當大多數節點存活時,Redis Cluster 才允許寫入。
- 自動數據遷移:當某個 master 失聯后,集群會選舉新的 master,并重新分配數據。
因此,對于分布式環境(多數據中心),Redis Cluster 比 Sentinel 更能避免腦裂問題。
4. 總結
問題 | 解決方案 |
---|---|
網絡分區導致的誤判 | 通過 down-after-milliseconds 設置合理的 Sentinel 宕機超時時間 |
防止腦裂 | 通過 min-slaves-to-write & min-slaves-max-lag 限制 master 行為 |
腦裂已發生 | 重新配置舊 master 為新 master 的 slave,并讓它重新同步數據 |
最佳方案 | 采用 Redis Cluster,利用多數派選舉防止 split-brain |
Redis Sentinel 適用于小型架構,但如果要保證高可用性和一致性,Redis Cluster 更可靠。
Redis Sentinel 使用場景?
Redis Sentinel 僅適用于主從(Master-Slave)模式,不能用于 Redis Cluster。它的主要目的是監控主從架構中的 master 和 slave,自動進行故障轉移(failover),保證高可用性。
Sentinel 適用的 Redis 部署模式
? 主從(Master-Slave)模式
- 主節點(master)負責讀寫,多個從節點(slave)負責讀取并復制主節點數據。
- Sentinel 負責監控 master 是否存活,并在故障時將某個 slave 選舉為新的 master。
? 哨兵模式(Sentinel Cluster)
- 多個 Sentinel 組成哨兵集群,監控 Redis 主從實例,通過投票決定故障轉移。
Sentinel 不能用于哪些場景?
? Redis Cluster(分片集群模式)
- Redis Cluster 本身已經支持高可用,采用數據分片和 Gossip 協議,不需要 Sentinel。
- 在 Redis Cluster 中,節點間通過投票機制進行主節點選舉,而 Sentinel 不能管理 Cluster。
? 單機 Redis
- 沒有 slave 的情況下,Sentinel 無法執行故障轉移,它的主要作用是監控主從結構。
- 如果只有一個 Redis 實例(單點),可以考慮使用 Keepalived + VIP 來做高可用。
如何選擇 Sentinel 還是 Redis Cluster?
特性 | Redis Sentinel(主從模式) | Redis Cluster(分片模式) |
---|---|---|
數據分片 | ? 不支持 | ? 支持 |
自動故障轉移 | ? 由 Sentinel 負責 | ? 由 Cluster 本身負責 |
客戶端連接方式 | 需通過 Sentinel 獲取 master | 直接連接 Redis Cluster |
適用于場景 | 讀多寫少,單機難以承受壓力 | 高并發、大數據量、分片存儲 |
數據一致性 | 只保證主從一致性,不防止腦裂 | 采用多數派選舉,防止腦裂 |
結論
- 如果你使用 Redis 主從模式 并希望實現高可用性,那么 Sentinel 是一個不錯的選擇。
- 如果你希望數據分片、擴展性更強,并且 不想依賴外部高可用組件,應該選擇 Redis Cluster。
簡單理解:
? 小型業務,主從讀多寫少 → 用 Sentinel
? 高并發、大規模數據 → 用 Redis Cluster