1. 程式人生 > >redis主從複製--------哨兵機制

redis主從複製--------哨兵機制

哨兵的介紹

sentinel,中文名是哨兵,

哨兵是redis叢集架構中非常重要的一個元件,主要功能如下

(1)叢集監控,負責監控redis master和slave程序是否正常工作
(2)訊息通知,如果某個redis例項有故障,那麼哨兵負責傳送訊息作為報警通知給管理員
(3)故障轉移,如果master node掛掉了,會自動轉移到slave node上
(4)配置中心,如果故障轉移發生了,通知client客戶端新的master地址

哨兵本身也是分散式的,作為一個哨兵叢集去執行,互相協同工作

(1)故障轉移時,判斷一個master node是宕機了,需要大部分的哨兵都同意才行,涉及到了分散式選舉的問題
(2)即使部分哨兵節點掛掉了,哨兵叢集還是能正常工作的,因為如果一個作為高可用機制重要組成部分的故障轉移系統本身是單點的,那就很坑爹了

哨兵的基礎知識

(1)哨兵至少需要3個例項,來保證自己的健壯性
(2)哨兵 + redis主從的部署架構,是不會保證資料零丟失的,只能保證redis叢集的高可用性
(3)對於哨兵 + redis主從這種複雜的部署架構,儘量在測試環境和生產環境,都進行充足的測試和演練

為什麼redis哨兵叢集只有2個節點無法正常工作?

數量為quorum的哨兵認為節點宕機了 那麼節點就宕機了。數量為majority的哨兵來進行選舉對應的Master節點。

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

   如果哨兵叢集僅僅部署了個2個哨兵例項,quorum=1,master宕機,s1和s2中只要有1個哨兵認為master宕機就可以還行切換,同時s1和s2中會選舉出一個哨兵來執行故障轉移。同時這個時候,需要majority,也就是大多數哨兵都是執行的,2個哨兵的majority就是2(2的majority=2,3的majority=2,5的majority=3,4的majority=2),2個哨兵都執行著,就可以允許執行故障轉移

哨兵進行主備切換時候出現的資料丟失問題

  • 非同步複製導致的資料丟失

        因為Master節點的資料要非同步進行同步到slave節點上,如果在複製的過程中Master就宕機了,就會出現資料丟失的問題。

  • 叢集腦裂導致的資料丟失

       腦裂的問題就是在資料叢集的狀態下,當Master節點的機器因為網路的原因(各種原因吧),有quorum數量的數量的機器認為Master已經宕機了,然後開始重新選舉產生一個Master節點。舊的Master節點處於一個假死的狀態。Client可以正常的連線Master,可以繼續向Master進行寫入資料,不會向新的Master節點進行輸入資料。等網路恢復(或者什麼別的原因)。舊的的Master重新迴歸叢集的時候。舊的Master成為了一個新的Slave,會重新複製新的Master上的資料。但是新的Master上的資料就會缺少。

哨兵主備切換時候資料丟失的問題解決方案

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

這兩個的配置的意思是:要求至少有1個slave,資料複製和同步的延遲不能超過10秒,如果說一旦所有的slave,資料複製和同步的延遲都超過了10秒鐘,那麼這個時候,master就不會再接收任何請求了。

上面兩個配置可以減少非同步複製和腦裂導致的資料丟失

哨兵叢集的自動發現機制

        哨兵互相之間的發現,是通過redis的pub/sub系統實現的,每個哨兵都會往__sentinel__:hello這個channel裡傳送一個訊息,這時候所有其他哨兵都可以消費到這個訊息。並感知到其他的哨兵的存在。每隔兩秒鐘,每個哨兵都會往自己監控的某個master+slaves對應的__sentinel__:hello channel裡傳送一個訊息,內容是自己的host、ip和runid還有對這個master的監控配置,每個哨兵也會去監聽自己監控的每個master+slaves對應的__sentinel__:hello channel,然後去感知到同樣在監聽這個master+slaves的其他哨兵的存在。每個哨兵還會跟其他哨兵交換對master的監控配置,互相進行監控配置的同步。

Save--->Master的選舉機制

  如果叢集中的Master認為宕機了。哨兵的叢集會進行重新選擇一個新的Master,選擇Master的原則有以下幾個:

  1. 與Master斷開的時長 
  2. 按照slave的優先順序進行排序,選擇優先順序高的。
  3. 如果優先順序相同,看從主節點中複製的資料量(也就是offset的值的大小)
  4. 如果以上兩個值相等話,就選擇一個 runid比較的一個值

哨兵的工作方式

       1. 每個Sentinel 以每秒鐘一次的頻率向它所知的主伺服器、從伺服器以及其他 Sentinel 例項傳送一個 PING 命令

        2. 如果一個例項(instance)距離最後一次有效回覆 PING 命令的時間超過 down-after-milliseconds 選項所指定的值, 那麼這個例項會被 Sentinel 標記為主觀下線。 一個有效回覆可以是: +PONG 、 -LOADING 或者-MASTERDOWN 。

        3. 如果一個主伺服器被標記為主觀下線, 那麼正在監視這個主伺服器的所有 Sentinel 要以每秒一次的頻率確認主伺服器的確進入了主觀下線狀態。

        4. 如果一個主伺服器被標記為主觀下線, 並且有足夠數量的 Sentinel (至少要達到配置檔案指定的數量)在指定的時間範圍內同意這一判斷, 那麼這個主伺服器被標記為客觀下線。

       5. 在一般情況下, 每個 Sentinel 會以每10 秒一次的頻率向它已知的所有主伺服器和從伺服器傳送 INFO 命令。 當一個主伺服器被 Sentinel 標記為客觀下線時, Sentinel 向下線主伺服器的所有從伺服器傳送 INFO 命令的頻率會從 10 秒一次改為每秒一次
       6. 當沒有足夠數量的 Sentinel 同意主伺服器已經下線, 主伺服器的客觀下線狀態就會被移除。 當主伺服器重新向 Sentinel 的 PING 命令返回有效回覆時, 主伺服器的主觀下線狀態就會被移除。