Redis高可用之戰:主從架構

Hello-Brand發表於2024-03-28

Redis24篇集合

1 主從模式介紹

在筆者的另外兩篇文章 《Redis系列:RDB記憶體快照提供持久化能力》、《Redis穩定性之戰:AOF日誌支撐資料持久化》中,我們介紹了Redis中的資料持久化技術,包括 RDB快照AOF日誌 。有了這兩個利器,我們再也不用擔心機器當機,資料丟失了。

但是持久化技術只是解決了Redis服務故障之後,快速資料恢復的問題。當機和資料恢復的過程中整個業務系統來說,還是有損失的,並沒有根本上提升可用性問題,而且持久化技術對於Redis服務效能來說是有損的。
我們需要的是保障Redis的高可用,減少甚至避免Redis服務發生當機的可能。

目前實現Redis高可用的模式主要有三種: 主從模式、哨兵模式、叢集模式。今天我們先來聊一下主從模式。
Redis 提供的主從模式,是透過複製的方式,將主伺服器上的Redis的資料同步複製一份到從 Redis 伺服器,這種做法很常見,MySQL透過binlog進行的主從複製也是這麼做的。
主節點的Redis我們稱之為master,從節點的Redis我們稱之為slave,主從複製為單向複製,只能由主到從,不能由從到主。可以有多個從節點,比如1主3從甚至n從,從節點的多少根據實際的業務需求來判斷。

2 主從架構如何保證資料一致性?

為了保證主伺服器Redis的資料和從伺服器Redis的資料的一致性,也為了分擔訪問壓力,均衡負載,應用層面一般採取讀寫分離的模式。
讀操作:主、從庫都可以執行,一般是在從庫上讀資料,對實時性和準確性有100%高真要求的部分業務,在謹慎評估之後也可以讀主庫,前提是不能給Master帶來高壓力和風險。
寫操作:只在主庫上寫資料,寫完之後將寫操作指令同步到從庫
參考下圖:
image

2.1 讀寫分離模式

讀寫分離模式的使用跟MySQL做讀寫分離的初衷是一樣的。因為我們已經劃分了主從庫,而且從庫的資料是由主庫單向複製的。如果主從庫都可以執行寫指令,那麼在高頻併發場景下對不同的副本資料做修改,操作會具有無序性,極易導致各副本產生資料不一致,這是分散式模式的弊病。 如果非要保證資料的強一致性,Redis 需要加鎖處理,或者使用佇列順序執行,這樣勢必降低Redis的效能,降低服務的吞吐能力,這就不是高效能Redis所能接受的。

2.2 主從複製和讀寫分離的意義

  • 故障隔離和恢復:無論主節點或者從節點當機,其他節點依然可以保證服務的正常執行,並可以手動或自動切換主從。
    • 如果Slave庫故障,則讀寫操作全部走到Master庫中
    • 如果Master庫故障,則將Slave轉成Master庫,僅丟失Master庫來不及同步到Slave的小部分資料
  • 讀寫隔離:Master 節點提供寫服務,Slave 節點提供讀服務,分攤流量壓力,均衡流量的負載。
  • 提供高可用保障:主從模式是高可用的最基礎版本,也是 sentinel 哨兵模式和 cluster 叢集模式實施的前置條件。

3 搭建Redis主從複製模式

Redis的主從架構中,主節點的資料更新會自動被複制到從節點,確保資料的一致性。主從複製的開啟,在從節點配置和發起即可,不需要我們在主節點做任何事情。
image

可以透過 replicaof(Redis 5.0 之前使用 slaveof)命令形成主庫和從庫的關係。在從節點開啟主從複製,如下:

說明:masterip:主機IP,masterport:主機埠號

3.1 主庫配置

# 設定Redis監聽的IP地址和埠號,預設監聽所有IP地址和6379埠
bind 0.0.0.0

# 啟用保護模式,允許遠端訪問
protected-mode no

# 指定Redis監聽的埠號
port 6380

# 增加Redis的最大記憶體限制,以容納更多資料
#maxmemory 16GB   增加記憶體限制,根據您的伺服器實際記憶體調整
maxmemory 20480mb

3.2 從庫配置

在從伺服器的配置檔案中加入

replicaof <masterip> <masterport>

假設現在有主例項 (10.21.125.1:6380)、從例項 A(10.21.125.2:6379)和 從例項 B (10.21.125.3:6379),在兩個從例項上分別執行以下命令,就成為了Slave,主例項成為 Master。

# 修改為從庫監聽的埠號
port 6379

# 新增需要同步的主庫資訊
replicaof 10.21.125.1 6380

4 主從複製原理

主從庫模式開啟之後,應用層面採用讀寫分離,所有資料的寫操作只會在主庫上進行,而讀操作基本會在從庫上進行(特殊情況下部分讀業務允許走主庫)。
主從會保持最終一致性:主庫有了資料更新之後,會立即同步給從庫,來保證主從庫的資料的一致的。

4.1 主從庫的同步機制

Redis 的主從複製機制均採用非同步複製,我們也稱為樂觀複製,這種複製方式意味著不能完全保證主庫和從庫資料的實時一致性。
Redis的主從複製機制可以根據不同的業務場景可以採用不同的應對方式。下面是一些主要場景及其對應的實現方案:

1. 首次配置完成主從庫之後的全量複製在從庫第一次連線到主庫時,將採用psync複製方式進行全量複製。 這意味著從庫會從頭開始複製主庫中的全部資料。
2. 主從正常執行期間,準實時同步在正常執行狀態下,從庫透過讀取主庫的緩衝區來進行增量複製。 這個過程涉及複製主庫上發生的新的資料變更。
3. 從庫第二次啟動(異常或主從網路斷開後恢復) Append增量資料 + 準實時同步將透過讀取主庫的緩衝區進行部分複製。 這種方式能夠快速同步中斷期間發生的資料變更,而不會對主庫造成重大影響。
image

PSYNC 命令是Redis中用於從節點與主節點之間資料同步的關鍵命令。它的工作原理包括以下幾個步驟:

1. 啟動或重連判斷:
當從節點(Slave)啟動或與主節點(Master)的連線斷開後重連時,從節點需要確定是否曾經同步過。
如果從節點沒有儲存任何主節點的執行ID(runid),它將視為第一次連線到主節點。

2. 首次同步處理:
如果是第一次同步的情況下,從節點會傳送 PSYNC -1 命令給主節點,代表請求全量資料同步。 全量同步是指主節點將其所有資料完整地Copy一份給從節點。

3. 主從重連後的處理:
對於之前已經同步過的從節點,它會傳送 PSYNC runid offset 命令,其中runid是主節點的唯一識別符號,offset是從節點上次同步資料的偏移量。這樣本質就是增量同步。

4. 主節點響應:
主節點接收到PSYNC命令後,會檢查runid是否匹配,以及offset是否在複製積壓緩衝區的範圍內。
如果匹配且offset有效,主節點將回復CONTINUE,併傳送自從節點上次斷開連線以來的所有寫命令。

5. 觸發全量同步的條件:
如果runid不匹配,或offset超出了積壓緩衝區的範圍,主節點將通知從節點執行全量同步,回覆FULLRESYNC runid offset

6. 積壓緩衝區的作用:
主節點會在處理寫命令的同時,將這些命令存入複製積壓佇列(緩衝池),同時記錄佇列中存放命令的全域性offset。
這樣做法是保證了效率。當從節點斷線重連,且條件允許時(runid和offset都具備),它可以透過offset從積壓佇列中進行增量複製,而不是全量複製,這樣複製的成本就低很多。

7. 保障資料一致性:
PSYNC機制允許從節點在網路不穩定或其他意外斷開連線的情況下,能夠以增量方式重新同步資料。這也是它的一大優勢,那就是保持主從節點資料的一致性。

8. 什麼時候啟動重連工作
判斷是否進行全量同步,需要考慮兩個關鍵因素:首先,確認這是否是第一次進行資料同步;其次,檢查快取區是否已經達到或超過其容量上限。只有在是第一次同步,或者快取區已溢位的情況下,才會執行全量同步。

4.2 1主n從的同步說明

如果你有多個從庫,則在每次連線的時候需要注意一些細節,如下:

  • 多個從庫情況下,每個從庫都會記錄自己的 slave_repl_offset,各自複製的進度也不相同。
  • 重連主庫進行恢復時,從庫會透過 psync 命令將 slave_repl_offset 告知主庫,主庫判斷從庫的狀態,來決定進行增量複製,還是全量複製。
  • replication buffer 和 repl_backlog 的說明
    • replication buffer 是主從庫在進行全量複製時,主庫上用於和從庫連線的客戶端的 buffer
    • repl_backlog_buffer 是為了支援從庫增量複製,主庫上用於持續儲存寫操作的一塊專用 buffer,所有從庫共享的
  • 主庫和從庫會各自記錄自己的複製進度,所以,不同的從庫在進行恢復時,需要將自己的複製進度(slave_repl_offset)發給主庫,主庫才可以按照偏移量取資料跟它同步。

如圖所示:
image

5 總結

  • 主從複製的作用一個是為分擔讀寫壓力,均衡負載,另一個是為了保證部分例項當機之後服務的持續可用性,所以Redis演變出主從架構和讀寫分離。
  • 主從複製的步驟包括:建立連線的階段、資料同步的階段、基於長連線的命令傳播階段。
  • 資料同步可以分為全量複製和部分複製,全量複製一般為第一次全量或者長時間主從連線斷開。
  • 主從模式是比較低階的可用性最佳化,要做到故障自動轉移,異常預警,高保活,還需要更為複雜的哨兵或者叢集模式,這個後面我們繼續介紹。

相關文章