【Redis】四種部署模式的介紹及其優缺點

kamier發表於2023-03-16

一、前言

說到Redis的部署模式,很多同學第一時間想到的就是Redis Cluster叢集模式,因為它可能是現在的主流模式。但其實這幾種模式各有優劣,實際環境中我們應該選擇合適的部署模式,否則適得其反,接下來簡單介紹一下這幾種部署模式

二、部署模式

2.1 單機模式

單機模式就是隻有單個redis提供服務,如下圖
image.png

  • 優點:

    1. 架構簡單,易於維護
  • 缺點:

    1. 單臺伺服器記憶體空間有限,無法存放太多的資料量
    2. 存在單點故障
    3. 讀寫壓力較大

單機模式適用於內部測試、專案規模小的場景

2.2 主從模式

由於單個redis節點的讀寫壓力較大,所以引出了主從複製方式,可實現讀寫分離,讀操作可以由slave節點來支援,降低master節點的壓力。如下圖
image.png

主從複製是redis實現高可用的基石,後續的兩種高可用方案 哨兵模式 或者 cluster叢集模式 都需要有主從複製的支撐。
  • 優點:

    1. 讀寫分離。透過讀寫分離來降低master節點的壓力
    2. 擁有多個資料副本
  • 缺點:

    1. 單個master記憶體空間有限,無法存放太多的資料量
    2. 依然只有master節點可以處理寫請求,存在瓶頸
    3. 當master節點發生故障下線時,需要人工地將某個slave節點切換為新的master節點,並且客戶端需要切換到連線新的master節點

主從模式適用於內部效能測試、專案規模小的場景

2.3 哨兵模式

哨兵模式是在主從複製的基礎上,新增哨兵(實際上就是個redis的應用程式)來監控master節點和slave節點,當master節點發生故障下線時,哨兵自動地將某個slave節點切換為master節點,且客戶端不需要去切換連線新的master節點。(一般需要部署哨兵叢集,防止哨兵的單點故障)
image.png

  • 優點:

    1. 讀寫分離。透過讀寫分離來降低master節點的壓力
    2. 擁有多個資料副本
    3. 自動故障轉移。當master節點發生故障下線時,哨兵自動地將某個slave節點切換為新的master節點,並且客戶端不需要切換連線新的master節點(由於客戶端連線哨兵叢集,而不直接連線master節點)
  • 缺點:

    1. 單個master記憶體空間有限,無法存放太多的資料量
    2. 依然只有master節點可以處理寫請求,存在瓶頸

哨兵模式適用於生產環境、專案規模中等的場景

2.3.1 故障轉移 failover

當master節點下線之後,哨兵自動將slave節點切換為新的master節點,這一過程稱為故障轉移(failover)。故障轉移的大致步驟如下:

  1. 檢測master是否主觀下線
    sentinel每隔1秒鐘,向所有的master、slave、sentinel傳送ping命令,透過其他伺服器的回覆來判斷是否線上(當ping的例項在連續down-after-milliseconds配置的時間內返回無效命令或無響應,則當前sentinel認為其主觀下線,對所有master、slave、sentinel都適用)
  2. 檢測master是否客觀下線
    當前sentinel要想判斷master是否客觀下線,需要詢問其他sentinel,並且認為master主觀下線的總數需要達到quorum配置的值,則當前sentinel將該master標記為客觀下線
  3. 選舉哨兵leader
    當前sentinel將該master標記為客觀下線後,會給其他sentinel再傳送命令,其他sentinel收到請求後將其設定為leader(這個設定是先到先得的,sentinel先收到誰的設定請求,就將誰設定為leader)。傳送命令的sentinel會根據其他sentinel回覆的結果來判斷自己是否被該sentinel設定為leader,如果當前sentinel被其他sentinel設定為leader的數量超過半數sentinel,那麼當前sentinel會認為自己已經成為leader,並開始後續故障轉移工作。如果沒有任何一個sentinel達到成為leader的要求,將會重新選舉直到產生leader為止
  4. 故障轉移由哨兵leader全權負責
    從slave列表中選擇最佳的slave作為新的master。讓其他slave複製新的master,並且繼續監聽舊master,如果其上線,將其設定為新的master的slave

2.4 叢集模式

既然哨兵模式已經具備了高可用性,為什麼還需要cluster模式?因為哨兵模式還是沒有解決只有master節點可以處理寫的問題,依然存在寫瓶頸。而cluster叢集模式使用"分片"(每個master處理一部分slot)的形式來處理所有key,可以有多個master來處理寫操作,從而來解決寫瓶頸問題。如下圖
image.png

  • 優點:

    1. 自動故障轉移。當某個master節點發生故障下線時,叢集自動地將其對應的某個slave節點替代它
    2. 當現有redis叢集不足以支撐整個系統的壓力時,可以橫向擴充叢集
  • 缺點:

    1. 無法執行批次操作,如mget
    2. 當redis節點很多的時候,由於每個節點都需要跟其他節點通訊,整個叢集的效能會降低
    3. 維護成本較高

redis cluster模式適用於生產環境、專案規模大型的場景

2.4.1 故障轉移 failover

與哨兵模式一樣,從節點的故障並不會影響叢集工作,對應的主節點只會記住自己的哪個從節點下線了,當從節點重連後,會繼續複製主節點的資料。

只有主節點故障才需要故障轉移。cluster叢集模式不需要哨兵,自身已具備了故障轉移功能。由於叢集內的每個節點都會互相進行通訊,節點之間透過gossip協議進行通訊,透過這種機制來發現故障並進行故障轉移。但是要達到故障轉移,需要解決幾個問題?

  • 故障發現:如何判斷某個master節點故障了?redis採用多數投票的方案
  • 選取slave節點:master有多個slave節點的時候,應該選擇哪個slave節點成為新的master

故障發現
和哨兵模式類似,故障發現也經歷兩個階段:PFAIL(主觀下線)和FAIL(客觀下線)
假設現在有3個master節點,分別為節點1,節點2,節點3。比如節點1判斷節點3下線,那麼它會標記節點3的狀態為PFAIL,節點1會透過gossip協議把這個資訊傳送給其他節點,接收到資訊的節點會進行對節點3客觀下線的狀態判定。當叢集中有超過半數的節點認為節點3處於PFAIL,那麼節點1就判定節點3為FAIL,並立即向叢集所有節點(包括節點3的子節點)廣播這個資訊。

故障轉移
當節點3的slave發現自己的master變為fail狀態時,便嘗試進行故障轉移failover,以成為新的master。由於一個master可能有多個slave,所以這些slave需要競爭成為master節點,過程如下:

  1. slave1、slave2都發現自己的master狀態變為fail
  2. 它們將自己記錄的叢集currentEpoch(選舉週期)加1,並使用gossip協議廣播failover_auth_request資訊
  3. 其他master節點收到slave1和slave2的訊息,會給slave1或slave2傳送failover_auth_ack,在一個選舉週期中,一個master只會響應第一個給它發訊息的slave
  4. slave們收集返回的failover_auth_ack,當收到超過半數的master的ack訊息後變成新的master
  5. 最後向整個叢集廣播現在自己是master,同時負責舊master所有slots的資訊
  6. 其他節點接收到資訊後,更新自己的維護狀態

三、總結

redis的部署模式介紹到這裡,總體看下來redis cluster叢集模式的利大於弊,所以在較大規模的專案中一般使用該模式,但在中小規模的專案中,選擇主從模式 或 哨兵模式亦可。

相關文章