爲何Redis 哨兵模式(Sentinel) 如此重要?說點個人想法

爲何須要哨兵模式(Sentinel)

  1. 只依靠持久化方案,在服務器下線後沒法恢復服務
  2. 使用主從複製,在 master 節點下線後,能夠手動將 slave 節點切換爲
    master,可是不能自動完成故障轉移

哨兵模式(Sentinel)

在這裏插入圖片描述

主要功能

  1. 監控(Monitoring):Sentinel會不斷的檢查你的主節點和從節點是否正常工做。
  2. 通知(Notification):被監控的Redis實例若是出現問題,Sentinel能夠經過API(pub)通知系統管理員或者其餘程序。
  3. 自動故障轉移(Automatic failover):若是一個 master 離線,Sentinel 會開始進行故障轉移,master下的一個slave 會被選爲新的 master,其餘的 slave 會開始複製新的 master。應用能夠經過 Redis服務的通知機制更新新的master 地址。
  4. 配置提供(Configuration provider):客戶端能夠把 Sentinel 做爲權威的配置發佈者來得到最新的 master地址。若是發生了故障轉移,Sentinel 集羣會通知客戶端新的 master 地址,並刷新 Redis 的配置。

主要配置

sentinel monitor : 監控的 redis 主節點
sentinel 是 redis 配置的提供者,而不是代理,客戶端只是從 sentinel 獲取數據節點的配置,所以這裏的 ip 必須是 redis 客戶端可以訪問的。
redis 源碼中提供了 sentinel 配置的模板:sentinel.confredis

Sentinel 啓動

$ redis-server sentinel.conf --sentinel
1
複製代碼
  1. 初始化一個普通的 redis 服務器
  2. 加載 Sentinel 專用配置,例如命令表、參數等,Sentinel 使用 sentinel.c 中的命令表、函數等配置,普通
    Redis 則使用 redis.c 中的配置
  3. 除了保存服務器通常狀態以外,Sentinel 還會保存 Sentinel 相關狀態

準備

Sentinel 與 master: Sentinel 監控 master,並經過 master 發現其餘 Sentinel 和 slaves
創建兩個異步網絡鏈接:算法

命令鏈接:用於向 Redis master 數據節點發送命令,例如經過 INFO 命令瞭解:數據庫

  • master 自己運行信息,用於更新本地的 master 字典(Redis Hash 的實現中用到字典使用的的也是這個數據結構)服務器

  • slaves 信息(角色、IP、Port、鏈接狀態、優先級、複製偏移量),用於更新本地的 slave 字典markdown

訂閱鏈接:訂閱 sentinel:hello 頻道,用於發現其餘 Sentinel,頻道中信息包括:網絡

  • Sentinel 自身信息(IP、Port、RunID、Epoch)
  • 監視的 Master 節點的信息(Name、IP、Port、Epoch)
    在這裏插入圖片描述

Sentinel 與 slave:Sentinel 自動發現 Slave

  1. Sentinel 向 master 節點發送 INFO 命令後獲取到全部 slave 的信息
    在這裏插入圖片描述
  2. Sentinel 與 slave 創建命令鏈接和訂閱鏈接
    在這裏插入圖片描述

Sentinel 之間:自動發現機制

  1. Sentinel 利用 pub/sub(發佈/訂閱)機制,訂閱了每一個 master 和 slave 數據節點的
    sentinel:hello 頻道,去自動發現其它也監控了統一 master 的 sentinel 節點
  2. Sentinel 向每 1s 向 sentinel:hello 中發送一條消息,包含了其當前維護的最新的 master
    配置。若是某個sentinel發現本身的配置版本低於接收到的配置版本,則會用新的配置更新本身的 master 配置
  3. 與發現的 Sentinel 之間相互創建命令鏈接,以後會經過這個命令鏈接來交換對於 master 數據節點的見解

監控

  1. 定時監控 Redis 數據節點
    一、每 10 秒每一個 sentinel 向 master、slaves 節點發送 INFO 命令
    二、每 2秒每一個 sentinel 經過 master 節點的 channel(名稱爲 sentinel:hello)交換信息(pub/sub),信息包括:
    三、每 1 秒每一個 sentinel 對其餘 sentinel 和 redis master,slave 發送 PING 命令,用於心跳檢測,做爲節點存活的判斷依據
  2. 主觀下線和客觀下線(發現故障)
    一、主觀下線(subjectively down,SDOWN):當前 Sentinel 實例認爲某個 redis服務爲」不可用」狀態。Sentinel 向 redis master 數據節點發送消息後30s(down-after-milliseconds) 內沒有收到有效回覆(+PONG、-LOADING 或者-MASTERDOWN),Sentinel 會將 master 標記爲下線(打開 master 結構中 flags 的 SRI_S_DOWN 標記)
    二、客觀下線(objectively down,ODOWN):多個 Sentinel 實例都認爲 master 處於 SDOWN 狀態,那麼此時 master 將處於 ODOWN, ODOWN能夠簡單理解爲master已經被集羣肯定爲」不可用」,將會開啓故障轉移機制。向其餘 sentinel 節點發送
    sentinel is-master-down-by-addr 消息詢問數據節點狀況,得知達到 quorum 數量的 sentinel節點認爲數據節點已經下線

處理

Sentinel 選舉(基於 Raft 算法),選出一個 Leader

在這裏插入圖片描述
投票:修改本地 leader 和 leader_epoch數據結構

  1. 對於已經投過票,身份變爲 Follower,在 2 倍故障轉移時間內再也不進行選舉(故障轉移的超時時間默認是3分鐘);沒投過票的變爲Candidate,執行第 2 步
  2. 更新故障轉移狀態爲start,epoch + 1,更新超時時間爲 1s 內隨機時間
  3. 向其餘節點發送 is-master-down-by-addr 命令請求投票。命令會帶上本身的epoch
  4. 2 倍故障轉移時間內選舉

Sentinel 選舉算法與 Raft 的區別:負載均衡

  1. 每次須要進行故障轉移前才進行選舉
  2. 增長了 quorum 參數,Candidate 須要的票數不只要超過一半,還要達到 quorum 參數配置的值
  3. Leader 不會將本身成爲 Leader 的消息發給其餘 Sentinel,其餘 Sentinel 等待Leader 從 slave
    選出 master後,檢測到新的 master 正常工做後,就會去掉舊的 master 客觀下線的標識,從而不須要進入故障轉移流程
    注意:
    1.在只有少數 Sentinel 進程正常運做的狀況下, Sentinel 是不能執行自動故障遷移的。
    2.正常狀況下要配置奇數哨兵,避免切換時候票數相同,出現競爭
    兩個節點出現競爭的投票過程
    在這裏插入圖片描述

故障轉移(切換 Redis master 數據節點)

sentinel master 選擇合適的 redis slave 成爲 master

slave 選擇標準:異步

1.健康的節點:ide

  • 在線的
  • 最近成功通訊過的(5s 內回覆過 PING 命令)
  • 數據比較新的(與 master 失聯時間不超過 10*down-after-milliseconds)
  • lave-priority(slave節點優先級)最高的slave節點
  • 制偏移量最大的 slave 節點(複製的最完整)
  • 擇 runId 最小的 slave 節點(啓動最先的節點)

2.執行 SLAVEOF no one(不會刪除已有數據,只是再也不接受主節點新的數據變化) 命令讓其成爲新的 master 節點。每秒 Sentinel 向其發送一次 INFO 命令,直到成功變爲 master

3.向剩餘的 slave 節點發送 SLAVEOF 新master 命令,讓他們成爲新 master 節點的 slave 節點

4.讓剩餘的 slave 複製新 master 的數據,經過配置 sentinel parallel-syncs(sentinel.conf) 規定了每次向新的主節點發起復制操做的從節點個數,parallel-syncs 取值越大,slave 完成複製的時間越快,可是對主節點的網絡負載、硬盤負載形成的壓力也越大,slave 加載 master 發來的 rdb 的過程當中不可用

5.更新原來master 節點配置爲 slave 節點,並保持對其進行關注,一旦這個節點從新恢復正常後,會命令它去複製新的master節點信息

6.所有故障轉移工做完成後,Leader Sentinel 就會推送 +switch-master 消息,同時重置 master,重置操做會釋放掉原來 master 所有的 slave 對象和監聽該 master 的其餘 Sentinel 對象,而後建立出新的 slave 對象
故障遷移過程當中 slave 可否返回數據給客戶端取決於 slave-serve-stale-data(redis.conf)

7.持續關注舊的 master,並在他從新上線後將它設置爲新 master 的 slave

在 sentinel 中執行 sentinel failover master 能夠強制該 sentinel 節點執行故障轉移,不與其餘節點進行選舉

Sentinel 缺陷

  1. Sentinel 模式下,寫操做仍然只能在 Sentinel 提供的 master 數據節點上執行,沒法負載均衡
  2. 持久化時 master節點刷盤阻塞,服務請求成功率降低
  3. slave 節點存儲能力受到單機的限制
  4. 分區問題:原 master redis 3 斷開與 redis 1 和 redis 2 的鏈接,此時 redis 1 和 redis 2 執行故障轉移,達到大多數,選擇 redis 1 爲 master。這樣,redis 1 和 redis 3 都能接受寫請求,但數據沒法同步,數據不一致
    在這裏插入圖片描述

爲何不用集羣模式(Cluster)

  1. 須要客戶端實現 Smart Client,完成重定向等工做
  2. 批量操做限制,不支持跨 slot 查詢,因此批量操做支持不友好
  3. Key 事務操做支持有限,只支持多 key 在同一節點上的事務操做,當多個 Key 分佈於不一樣的節點上時沒法使用事務功能
  4. Key 做爲數據分區的最小粒度,不能將一個很大的鍵值對象如hash、list 等映射到不一樣的節點
  5. 不支持多數據庫空間,單機下的 redis 能夠支持到 16 個數據庫,集羣模式下只能使用 1個數據庫空間,即 db 0

參考

  1. Redis Sentinel Documentation
  2. 深刻學習Redis(4):哨兵
  3. Redis 設計與實現
  4. Redis深度歷險:核心原理與應用實踐

源自:劉聰

看到這裏的小夥伴,若是你喜歡這篇文章的話,別忘了轉發、收藏、留言互動

若是對文章有任何問題,歡迎在留言區和我交流~

最近我新整理了一些Java資料,包含面經分享、模擬試題、和視頻乾貨,若是你須要的話,歡迎私信我

給大家康康都有哪些:

相關文章
相關標籤/搜索