主從模式配置
對於 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 文件進行全量復制,同時將新寫入的命令存儲進緩沖區,發送給從節點,從而保證數據一致性;
為了減少數據同步給主節點帶來的壓力,可以通過從節點級聯的方式進行同步。
網絡開小差了
網絡斷連重新連接后,主從節點通過分別維護的偏移量來同步寫命令。