Sentinel使用


基本原理

Sentinel 的原理並不復雜:

  • 啟動 n 個 sentinel 實例,這些 sentinel 實例會去監控你指定的 redis master/slaves
  • 當 redis master 節點掛掉后, Sentinel 實例通過 ping 檢測失敗發現這種情況就認為該節點進入 SDOWN 狀態,也就是檢測的 sentinel 實例主觀地(Subjectively)認為該 redis master 節點掛掉。
  • 當一定數目(Quorum 參數設定)的 Sentinel 實例都認為該 master 掛掉的情況下,該節點將轉換進入 ODOWN 狀態,也就是客觀地(Objectively)掛掉的狀態。
  • 接下來 sentinel 實例之間發起選舉,選擇其中一個 sentinel 實例發起 failover 過程:從 slave 中選擇一台作為新的 master,讓其他 slave 從新的 master 復制數據,並通過 Pub/Sub 發布事件。
  • 使用者客戶端從任意 Sentinel 實例獲取 redis 配置信息,並監聽(可選) Sentinel 發出的事件: SDOWN, ODOWN 以及 failover 等,並做相應主從切換,Sentinel 還扮演了服務發現的角色。
  • Sentinel 的 Leader 選舉采用的是 Raft 協議

一張示意圖,正常情況下:

Sentinel 原理

當 M1 掛掉后:

Sentinel 原理

節點 2 被提升為 master,Sentinel 通知客戶端和 slaves 去使用新的 Master。

搭建實驗環境

  • 兩個 redis,一個主一個從,分別監聽在 6379 和 6380 端口
1
2 
$ redis-server $ redis-server --port 6380 
  • redis-cli -p 6380 連上 6380 端口的 redis,執行 slaveof 127.0.0.1 6379 將它設置為 6379 的 slave。
  • 啟動三個 sentinel 實例,分別監聽在 5000 - 5002 端口,並且監控 6379 的 redis master,首先是配置文件

s1.conf:

1
2 3 4 
port 5000 sentinel monitor mymaster 127.0.0.1 6370 2 sentinel down-after-milliseconds mymaster 1000 sentinel failover-timeout mymaster 60000 

其他兩個配置文件是 s2.conf 和 s3.conf 只是將 port 5000 修改為 5001 和 5002,就不再重復。需要確保配置文件是可寫的,因為 Sentinel 會往配置文件里添加很多信息作為狀態持久化,這是為了重啟等情況下可以正確地恢復 sentinel 的狀態。

啟動:

1
2 3 
$ redis-sentinel s1.conf $ redis-sentinel s2.conf $ redis-sentinel s3.conf 

配置說明:

  • port ,指定 sentinel 啟動后監聽的端口,sentinel 實例之間需要通過此端口通訊。
  • sentinel monitor [name] [ip] [port] [quorum],最重要的配置,指定要監控的 redis master 的 IP 和端口,給這個監控命名 name。Quorum 指定至少多少個 sentinel 實例對 redis master 掛掉的情況達成一致,只有達到這個數字后,Sentinel 才會去開始一次 failover 過程。
  • down-after-milliseconds,設定 Sentinel 發現一個 redis 沒有響應 ping 到 Sentinel 認為該 redis 實例不可訪問的時間。
  • failover-timeout,Sentinel 實例投票對於同一個 master 發起 failover 過程的間隔時間,防止同時開始多次 failover。

Sentinel 啟動后會輸出類似的日志:

1
2 
17326:X 13 Oct 12:00:55.143 # +monitor master mymaster 127.0.0.1 6379 quorum 2 17326:X 13 Oct 12:00:55.143 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379 

表示開始監控 mymaster 集群,並輸出集群的基本信息。

以及 Sentinel 之間的感知日志,比如 s3 節點的輸出:

1
2 
18441:X 13 Oct 12:01:39.985 * +sentinel sentinel eab05ac9fc34d8af6d59155caa195e0df5e80d73 127.0.0.1 5000 @ mymaster 127.0.0.1 6379 18441:X 13 Oct 12:01:52.918 * +sentinel sentinel 4bf24767144aea7b4d44a7253621cdd64cea6634 127.0.0.1 5002 @ mymaster 127.0.0.1 6379 

查看信息

可以用 redis-cli 連上 sentinel 實例,查看信息:

1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 
$ redis-cli -p 5000 127.0.0.1:5000> sentinel master mymaster  1) "name"  2) "mymaster"  3) "ip"  4) "127.0.0.1"  5) "port"  6) "6379"  7) "runid"  8) "4b97e168125b735e034d49c7b1f45925f43aded9"  9) "flags" 10) "master" 11) "link-pending-commands" 12) "0" 13) "link-refcount" 14) "1" 15) "last-ping-sent" 16) "0" 17) "last-ok-ping-reply" 18) "729" 19) "last-ping-reply" 20) "729" 21) "down-after-milliseconds" 22) "1000" 23) "info-refresh" 24) "6258" 25) "role-reported" 26) "master" 27) "role-reported-time" 28) "11853370" 29) "config-epoch" 30) "0" 31) "num-slaves" 32) "1" 33) "num-other-sentinels" 34) "2" 35) "quorum" 36) "2" 37) "failover-timeout" 38) "60000" 39) "parallel-syncs" 40) "1" 

sentinel master [name] 用於查看監控的某個 redis master 信息,包括配置和狀態等,其他命令還包括:

  • sentinel masters 查看所有監控的 master 信息。
  • sentinel slaves [name] 查看監控的某個 redis 集群的所有 slave 節點信息。
  • sentinel sentinels [name] 查看所有 sentinel 實例信息。

更重要的一個命令是根據名稱來查詢 redis 信息,客戶端會用到:

1
2 3 
127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster 1) "127.0.0.1" 2) "6379" 

測試 Failover

我們讓 6379 的 master 主動休眠 30 秒來觀察 failover 過程:

1
$ redis-cli -p 6379 DEBUG sleep 30 

我們可以看到每個 sentinel 進程都監控到 master 掛掉,從 sdown 狀態進入 odown,然后選舉了一個 leader 來進行 failover,最終 6380 成為新的 master, sentinel 的日志輸出:

1
2 3 4 5 6 7 8 9 10 
18441:X 13 Oct 15:26:51.735 # +sdown master mymaster 127.0.0.1 6379 18441:X 13 Oct 15:26:51.899 # +new-epoch 1 18441:X 13 Oct 15:26:51.900 # +vote-for-leader eab05ac9fc34d8af6d59155caa195e0df5e80d73 1 18441:X 13 Oct 15:26:52.854 # +odown master mymaster 127.0.0.1 6379 #quorum 3/2 18441:X 13 Oct 15:26:52.854 # Next failover delay: I will not start a failover before Thu Oct 13 15:28:52 2016 18441:X 13 Oct 15:26:53.034 # +config-update-from sentinel eab05ac9fc34d8af6d59155caa195e0df5e80d73 127.0.0.1 5000 @ mymaster 127.0.0.1 6379 18441:X 13 Oct 15:26:53.034 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380 18441:X 13 Oct 15:26:53.034 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380 18441:X 13 Oct 15:26:54.045 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380 18441:X 13 Oct 15:27:20.383 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6380 

日志的幾個主要事件:

  • +sdown master mymaster 127.0.0.1 6379,發現 master 檢測失敗,主觀認為該節點掛掉,進入 sdown 狀態。
  • +odown master mymaster 127.0.0.1 6379 #quorum 3/2,有兩個 sentinel 節點認為 master 6379 掛掉,達到配置的 quorum 值 2,因此認為 master 已經客觀掛掉,進入 odown 狀態。
  • +vote-for-leader eab05ac9fc34d8af6d59155caa195e0df5e80d73 准備選舉一個 sentinel leader 來開始 failover。
  • +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6380 切換 master 節點, failover 完成。
  • +config-update-from sentinel eab05ac9fc34d8af6d59155caa195e0df5e80d73 127.0.0.1 5000 @ mymaster 127.0.0.1 6379 更新 sentinel 配置。
  • 6379 休眠回來,作為 slave 掛載到 6380 后面,可見 sentinel 確實同時在監控 slave 狀態,並且掛掉的節點不會自動移除,而是繼續監控。

此時查看 sentinel 配置文件,會發現增加了一些內容:

1
2 3 4 5 6 7 8 9 
# Generated by CONFIG REWRITE dir "/Users/dennis/opensources/redis-sentinel" sentinel failover-timeout mymaster 60000 sentinel config-epoch mymaster 1 sentinel leader-epoch mymaster 1 sentinel known-slave mymaster 127.0.0.1 6379 sentinel known-sentinel mymaster 127.0.0.1 5001 8ba1e75cbf4c268be4a2950ee7389df746c6b0b4 sentinel known-sentinel mymaster 127.0.0.1 5002 4bf24767144aea7b4d44a7253621cdd64cea6634 sentinel current-epoch 1 

可以看到 sentinel 將最新的集群狀態寫入了配置文件。

運維

命令

除了上面提到的一些查看信息的命令之外, sentinel 還支持下列命令來管理和檢測 sentinel 配置:

  • SENTINEL reset <pattern> 強制重設所有監控的 master 狀態,清除已知的 slave 和 sentinel 實例信息,重新獲取並生成配置文件。
  • SENTINEL failover <master name> 強制發起一次某個 master 的 failover,如果該 master 不可訪問的話。
  • SENTINEL ckquorum <master name> 檢測 sentinel 配置是否合理, failover 的條件是否可能滿足,主要用來檢測你的 sentinel 配置是否正常。
  • SENTINEL flushconfig 強制 sentinel 重寫所有配置信息到配置文件。

增加和移除監控以及修改配置參數:

  • SENTINEL MONITOR <name> <ip> <port> <quorum>
  • SENTINEL REMOVE <name>
  • SENTINEL SET <name> <option> <value>

增加和移除 Sentinel

增加新的 Sentinel 實例非常簡單,修改好配置文件,啟動即可,其他 Sentinel 會自動發現該實例並加入集群。如果要批量啟動一批 Sentinel 節點,最好以 30 秒的間隔一個一個啟動為好,這樣能確保整個 Sentinel 集群的大多數能夠及時感知到新節點,滿足當時可能發生的選舉條件。

移除一個 sentinel 實例會相對麻煩一些,因為 sentinel 不會忘記已經感知到的 sentinel 實例,所以最好按照下列步驟來處理:

  • 停止將要移除的 sentinel 進程。
  • 給其余的 sentinel 進程發送 SENTINEL RESET * 命令來重置狀態,忘記將要移除的 sentinel,每個進程之間間隔 30 秒。
  • 確保所有 sentinel 對於當前存貨的 sentinel 數量達成一致,可以通過 SENTINEL MASTER [mastername] 命令來觀察,或者查看配置文件。

客戶端實現

客戶端從過去直接連接 redis ,變成:

  1. 先連接一個 sentinel 實例
  2. 使用 SENTINEL get-master-addr-by-name master-name 獲取 redis 地址信息。
  3. 連接返回的 redis 地址信息,通過 ROLE 命令查詢是否是 master。如果是,連接進入正常的服務環節。否則應該斷開重新查詢。
  4. (可選)客戶端可以通過 SENTINEL sentinels [name] 來更新自己的 sentinel 實例列表。

當 Sentinel 發起 failover 后,切換了新的 master,sentinel 會發送 CLIENT KILL TYPE normal 命令給客戶端,客戶端需要主動斷開對老的master 的鏈接,然后重新查詢新的 master 地址,再重復走上面的流程。這樣的方式仍然相對不夠實時,可以通過 sentinel 提供的 Pub/Sub 來更快地監聽到 failover 事件,加快重連。

如果需要實現讀寫分離,讀走 slave,那可以走 SENTINEL slaves [name] 來查詢 slave 列表並連接。

生產環境推薦

對於一個最小集群,Redis 應該是一個 master 帶上兩個 slave,並且開啟下列選項:

1
2 
min-slaves-to-write 1 min-slaves-max-lag 10 

這樣能保證寫入 master 的同時至少寫入一個 slave,如果出現網絡分區阻隔並發生 failover 的時候,可以保證寫入的數據最終一致而不是丟失,寫入老的 master 會直接失敗,參考 Consistency under partitions

Slave 可以適當設置優先級,除了 0 之外(0 表示永遠不提升為 master),越小的優先級,越有可能被提示為 master。如果 slave 分布在多個機房,可以考慮將和 master 同一個機房的 slave 的優先級設置的更低以提升他被選為新的 master 的可能性。

考慮到可用性和選舉的需要,Sentinel 進程至少為 3 個,推薦為 5 個,如果有網絡分區,應當適當分布(比如 2 個在 A 機房, 2 個在 B 機房,一個在 C 機房)等。

其他

由於 Redis 是異步復制,所以 sentinel 其實無法達到強一致性,它承諾的是最終一致性:最后一次 failover 的 redis master 贏者通吃,其他slave 的數據將被丟棄,重新從新的 master 復制數據。此外還有前面提到的分區帶來的一致性問題。

其次,Sentinel 的選舉算法依賴時間,因此要確保所有機器的時間同步,如果發現時間不一致,Sentinel 實現了一個 TITL 模式來保護系統的可用性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM