面試官:Redis 主從複製時網路開小差了怎麼整?

*IT界農民工*發表於2020-11-16

上週因為實在太忙就認認真真寫了一篇水文,吹了一下自己過去的經歷,反響竟然超出了我的預期,並且後臺還有讀者留言表示想看續集的。哈哈,果然大家還是對水文更有熱情。

這期我們繼續回到之前的 Redis 話題。今天主要講的是主從複製資料一致性相關以及面對網路中斷如何進行資料同步的問題。

不 BB 了,直接上鍾吧!

圖注:思維導圖

主從模式配置

對於 Redis 主從大家可能並不陌生,但是配置的話日常工作中並不會經常操作。在這裡簡單介紹下主從的相關配置。

1、主從模式

Redis 中設定主從的方式很簡單,通常有兩種:

  • 通過在配置檔案 redis.conf 中設定 slaveof 方式(永久);

  • 直接在客戶端執行 slaveof ip port 的方式(臨時);

2、主-從-從模式

對於主-從-從的模式來說,配置也與上邊的操作類似,在這裡就不多贅述了。

主從一致性原理

瞭解了主從配置後,下面就要進入正題了。

在主從中,通常的操作是主庫用來寫入資料,從庫用來讀取資料。這樣的好處是避免了所有的請求壓力都打在了主庫上,同時系統的伸縮性也得到了很大的提升。 

但是問題就來了,讀從庫時的資料要與主庫保持一致,那就需要主庫的資料在寫入後同步到從庫中。如何保持主庫與從庫的資料一致性,當有多個從庫時,又如何做到呢?

1、全量複製

這是第一次同步時所發生的傳遞關係。看名字就知道,主庫第一次就毫無保留的把所有資料都傳遞給了從庫。 

我們先來看下它們是如何發生第一次關係的(就知道你會想歪)。

圖中的同步流程已經很清晰了,總共分為三部分:

(1)主從節點建立聯絡

當從節點與主節點第一次建立聯絡時,從節點會向主節點傳送 psync 命令,表示要進行資料同步。

正如你看到的 psync 命令後會帶有兩個引數:一個是 runID,一個是偏移量 offset。

  • runID:每個Redis例項生成的隨機且唯一的ID,在這裡表示的是主節點的ID。

  • offset:複製偏移量。

在圖中第一次複製時因為不知道主庫ID和偏移量,因此用“?”和“-1”分別來表示runID 和 offset。 

當主節點接收到 psync 命令後,會使用 FULLSYNC命令向從節點傳送 runID 及offset 兩個引數。從節點將其資訊儲存下來。

到這裡關係算是建立了下來。

(2)主節點同步RDB檔案

RDB檔案,這是一個老面孔了,持久化時會用到的二進位制檔案。在這裡起著主從資料同步的作用,也就是說主從同步是依賴 RDB 檔案來實現的。

從節點接收到 RDB 檔案後,在本地完成資料載入,算是完成了主從同步。 

到這裡你有沒有發現什麼問題?

我們回想下 RDB 檔案是如何生成的。在持久化那篇文章裡,我們介紹過,父程式 fork 了一個子程式來進行生成 RDB 檔案。父程式並不阻塞接收處理客戶端的命令。 

那麼問題就產生了,當主節點把 RDB 檔案傳送給從節點時,主節點同時接收的命令又該如何來處理? 

(3)主節點同步緩衝區命令

這一步就是來解決 RDB 檔案生成後,父程式又接收到寫命令同步的問題的。 

為了保證主從節點資料的一致性,主節點中會使用緩衝區來記錄 RDB 檔案生成後接收到的寫操作命令。在 RDB 檔案傳送完成後會把緩衝區的命令傳送給從節點來執行。

到這裡,主從節點的資料同步算是完成了。

2、級聯操作

我們再來回顧下整個同步流程,從建立關係,生成 RDB 檔案,傳輸給從節點到最後緩衝區命令傳送給從節點。這是一個從節點與主節點同步的完整流程。

那麼我們再來思考:當有多個從節點,也就是一主多從時,第一次連線時都要進行全量複製。但是在生成 RDB 檔案時,父程式 fork 子程式時可能會出現阻塞,同時在傳輸 RDB 檔案時也會佔用頻寬,浪費資源。

這種情況我們該如何來解決呢?

不知道你對文章開頭的 主-從-從模式是否還有印象。通過對從節點再建立從節點。同步資料時從級聯的從節點上進行同步,從而就減輕了主節點的壓力。

網路開小差了

上面的流程我們已經知道了正常情況下主從節點的複製過程了,但是當網路中斷導致主從連線失敗等異常情況下,主從同步又是如何來進行的? 

在這裡要提到一個增量複製的名詞,與全量複製不同的是,它是根據主從節點的偏移量來進行資料同步的。

什麼意思呢?

還記得在全量複製裡我們所提到過的緩衝區嗎?就是用來儲存生成 RDB 檔案後的寫命令的,這裡我們稱為緩衝區A。主從節點斷開連線後,除了會將後續接收到的寫命令寫入緩衝區A的同時,還會寫入到另一個緩衝區B裡。

在緩衝區B裡,主從節點分別會維護一個偏移量 offset。剛開始時,主節點的寫位置與從節點的讀位置在同一起點,隨著主節點的不斷寫入,偏移量也會逐漸增大。同樣地,從節點複製完後偏移量也在不斷增加。

當網路斷開連線時,從節點不再進行同步,此時主節點由於不斷接收新的寫操作的偏移量會大於從節點的偏移量。當連線恢復時,從節點向主節點傳送帶有偏移量的psync 命令,主節點根據偏移量來進行比較,只需將未同步寫命令同步給從節點即可。

總結

主從一致性原理

  • 從節點第一次進行連線時,主節點會生成 RDB 檔案進行全量複製,同時將新寫入的命令儲存進緩衝區,傳送給從節點,從而保證資料一致性;

  • 為了減少資料同步給主節點帶來的壓力,可以通過從節點級聯的方式進行同步。

網路開小差了

  • 網路斷連重新連線後,主從節點通過分別維護的偏移量來同步寫命令。 

關於作者

作者:大家好,我是萊烏,BAT搬磚工一枚。從小公司進入大廠,一路走來收穫良多,想將這些經驗分享給有需要的人,因此建立了公眾號「IT界農民工」。定時更新,希望能幫助到你。

面試官:Redis 主從複製時網路開小差了怎麼整?

相關文章