老司機帶你玩轉面試(4):Redis 高可用之哨兵模式

前文回顧

建議前面文章沒看過的同窗先看下前面的文章:java

「老司機帶你玩轉面試(1):緩存中間件 Redis 基礎知識以及數據持久化」node

「老司機帶你玩轉面試(2):Redis 過時策略以及緩存雪崩、擊穿、穿透」git

「老司機帶你玩轉面試(3):Redis 高可用之主從模式」github

哨兵模式

前面介紹了 Redis 的主從模式,主從模式只能實現讀高可用,致命的弱點是寫沒法高可用,一旦 master 節點掛了,整個集羣將沒法寫入數據,這並不符合咱們對 Redis 高可用集羣的指望。面試

那麼,是否是有一種方法,能夠作到不只僅讀高可用,寫同樣要高可用,固然有,這就是咱們今天要介紹的哨兵模式。redis

哨兵模式能夠理解成主從模式的一個升級版,主從模式 master 節點和 slave 節點是一開始就定好的,而在哨兵模式中, master 節點是能夠轉移,一旦發現當前的 master 節點掛掉,經過選舉能夠指定一個 slave 節點晉升成爲 master ,保證在任何狀況下,都有 master 節點能夠支持寫入操做,也間接實現了寫高可用。shell

簡介

哨兵模式能夠看作是前面主從模式的一個升級版,主從模式沒有故障轉移, master 節點掛了就掛了,而哨兵模式就是爲了解決這個問題而出現的。緩存

  • 集羣監控:負責監控 Redis master 和 slave 進程是否正常工做。
  • 消息通知:若是某個 Redis 實例有故障,那麼哨兵負責發送消息做爲報警通知給管理員。
  • 故障轉移:若是 master node 掛掉了,會自動轉移到 slave node 上。
  • 配置中心:若是故障轉移發生了,通知 client 客戶端新的 master 地址。

核心

假如咱們如今有兩個哨兵實例,就長下面這樣:網絡

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+
複製代碼

再瞭解兩個參數: quorum 、 majority架構

  • quorum: 表示認爲 master 宕機的哨兵數量。
  • majority: 表示受權進行主從切換的最少的哨兵數量,而這個數字,須要大於一半。

在只有兩個節點的狀況下,若是 master 宕機, s1 和 s2 中只要有 1 個哨兵認爲 master 宕機了,就能夠進行切換,同時 s1 和 s2 會選舉出一個哨兵來執行故障轉移。

這時,須要 majority,也就是大多數哨兵都是運行的。

因此此時,若是此時僅僅是 M1 進程宕機了,哨兵 s1 正常運行,那麼故障轉移是 OK 的。可是若是是整個 M1 和 S1 運行的機器宕機了,那麼哨兵只有 1 個,此時就沒有 majority 來容許執行故障轉移,雖然另一臺機器上還有一個 R1,可是故障轉移不會執行。

因此就有了如下這一條建議:

  • 哨兵至少須要 3 個實例,來保證本身的健壯性,而且實例數量最好是奇數。

由於在進行選舉的時候,須要超過一半的哨兵贊成,也就是 majority 。

2 個哨兵,majority=2
3 個哨兵,majority=2
4 個哨兵,majority=2
5 個哨兵,majority=3
6 個哨兵,majority=3
7 個哨兵,majority=4
...
複製代碼

能夠看到,只有在奇數的時候,是能夠最大化的利用 majority 數量。

經典的三哨兵模型下面這樣:

+----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+
複製代碼

若是 M1 所在機器宕機了,那麼三個哨兵還剩下 2 個,S2 和 S3 能夠一致認爲 master 宕機了,而後選舉出一個來執行故障轉移,同時 3 個哨兵的 majority 是 2,因此還剩下的 2 個哨兵運行着,就能夠容許執行故障轉移。

Redis 哨兵模式數據丟失問題

首先先說一個結論:

  • 哨兵 + Redis 主從的部署架構,是不保證數據零丟失的,只能保證 Redis 集羣的高可用性。

而後咱們再說兩種會致使數據丟失的狀況:

第一種:是異步複製可能會致使數據丟失

因爲 master 向 salve 複製數據是異步,有可能,有部分數據尚未向 salve 複製,這時 master 宕機了,那麼這部分數據就丟失了。

第二種:腦裂致使的數據丟失

腦裂是指,因爲網絡波動或者其餘因素影響, master 所在的機器忽然間沒法被其餘哨兵梭訪問到,可是實際上這個 master 節點還在正常運行中。

此時哨兵會覺得這個 master 節點已經宕機,開始進行新的 master 節點的選舉,將其餘的 salve 節點切換成了 master 節點,這時集羣中就會存在兩個 master 節點,也就是腦裂產生了。

這時雖然產生了新的 master 節點,可是客戶端可能還沒進行切換,還在像老的 master 寫數據,可是當老的 master 恢復訪問的時候,會被做爲一個 salve 掛載到新的 master 節點上,本身的數據會被清空,從新重新的 master 複製數據,而在腦裂過程當中寫入老的 master 的數據就這麼沒了。

數據丟失的解決方案有麼?沒有,由於這個問題是客觀存在的,咱們解決不了這個問題,只能儘可能的去減小這個問題帶來的損失,這時,可使用下面這兩個配置:

min-slaves-to-write 1
min-slaves-max-lag 10
複製代碼

這兩個配置的意思是:

兩個參數的意思:

  • 要求至少有 1 個 slave ,數據複製和同步的延遲不能超過 10 秒。
  • 若是說一旦全部的 slave ,數據複製和同步的延遲都超過了 10 秒鐘,那麼這個時候, master 就不會再接收任何請求了。

(1) 減小異步複製的數據丟失:

有了 min-slaves-max-lag 這個配置,就能夠確保說,一旦 slave 複製數據和 ack 延時太長,就認爲可能 master 宕機後損失的數據太多了,那麼就拒絕寫請求,這樣能夠把 master 宕機時因爲部分數據未同步到 slave 致使的數據丟失下降的可控範圍內。

(2) 減小腦裂的數據丟失:

若是一個 master 出現了腦裂,跟其餘 slave 丟了鏈接,那麼上面兩個配置能夠確保說,若是不能繼續給指定數量的 slave 發送數據,並且 slave 超過 10 秒沒有給本身 ack 消息,那麼就直接拒絕客戶端的寫請求。

這樣腦裂後的舊 master 就不會接受 client 的新數據,也就避免了數據丟失。

上面的配置就確保了,若是跟任何一個 slave 丟了鏈接,在 10 秒後發現沒有 slave 給本身 ack ,那麼就拒絕新的寫請求

所以在腦裂場景下,最多就丟失 10 秒的數據。

主觀宕機和客觀宕機

  • sdown: 主觀宕機,就一個哨兵若是本身以爲一個 master 宕機了,那麼就是主觀宕機。
  • odown: 客觀宕機,若是 quorum 數量的哨兵都以爲一個 master 宕機了,那麼就是客觀宕機。

sdown 達成的條件很簡單,若是一個哨兵 ping 一個 master,超過了 is-master-down-after-milliseconds 指定的毫秒數以後,就主觀認爲 master 宕機了;若是一個哨兵在指定時間內,收到了 quorum 數量的其它哨兵也認爲那個 master 是 sdown 的,那麼就認爲是 odown 了。

參考

github.com/doocs/advan…

blog.csdn.net/weixin_4066…

您的掃碼關注,是對小編堅持原創的最大鼓勵:)
相關文章
相關標籤/搜索