徹底明白Redis主從同步原理

1.主從複製

兩個Redis實例(可ip相同port不同),可使用slaveof命令設置主從關係。redis採用樂觀同步策略,即容忍短時間內主從不一致,但是保證最終一致性,主從複製分爲三個階段:

  1. 連接階段
  2. 數據同步階段
  3. 命令傳播階段

2.連接階段

當slave執行完salveof ${master_ip} ${master_port}命令時,slave向master發起socket連接,master接收到連接請求後建立連接。

當連接建立後,slave向master發送[ping]命令,以確定master狀態正常,如果master響應[pong]則代表master正常。

如果master設置了密碼,則slave需要配置masterauth參數,此時slave發送[auth + ${passwoed}]命令進行密碼驗證,

當密碼驗證成功後,slave通知master自己的監聽端口,此時連接完成。

3.數據同步階段

數據同步階段是slave的數據初始化階段,也就是slave同步master當前的數據,該步是slave主動發起。

slave向master發送[psync]命令,master收到請求後,首先判斷是增量複製還是全量複製,然後再同步。

增量複製是指master僅將緩衝區中的命令發給slave,slave依次執行命令,完成數據同步。

全量複製是指master先生成內存快照(rdb文件,這裏和是否開啓rdb備份無關),然後將內存快照發給slave,slave加載快照到內存中完成數據同步。

3.1 offset 偏移量

master和slave都會維護一個偏移量(可使用[info replication]命令查看偏移量),用於標識主從複製的現狀;master的offset表示向slave已發送的字節數,slave的offset表示已同步的字節數。可以通過offset觀察主從是否同步完成,若相等則說明同步完成。
在這裏插入圖片描述

3.2 replication backlog buffer

[replication backlog buffer]是一個固定長度的FIFO的隊列,大小由配置參數[repl-backlog]指定,默認大小是1mb,這個緩衝區只存在master,用於備份最近master同步slave的數據。

在命令傳播階段,master除了將命令同步給slave外還會在這個緩衝區中備份,而且還會存儲每個命令(實際是每個字節)對用的offset值,如下圖:
在這裏插入圖片描述
由於緩衝區固定大小,因此只能備份最近執行過的命令,這個緩衝區用於增量複製,提高數據同步階段的效率。

3.3 runid

每個redis服務每次啓動時,都會隨機生成一個40的id來代表自己,可通過[info server]命令查詢run_id。

在初次主從同步時,master會將自己的runid發送給slave,salve記錄自己的[master runid]。

3.4 同步流程

在這裏插入圖片描述

  1. slave首先判斷是否第一次執行主從複製,即如果有保存的[master run_id],如果有則說明不是第一次。

  2. 如果slave是第一次執行主從複製,則向master發送全量複製請求。

  3. 如果slave不是第一次執行主從複製,則向master發送增量複製請求[ psync ${master run_id} offset ]。

  4. master如果接受到全量複製請求,則進行內存快照,然後響應rdb文件。

  5. master如果接受到增量複製請求,則首先判斷請求中的runid是不是自己,如果和自己的runid不一致,則說明slave之前的master並不是自己,此時只能進行全量複製,響應[ FULLRESYNC runid offset ],從節點則更新自己保存的master runid,並將offset作爲自己的初始偏移量,然後等待master發來的rdb文件進而執行全量複製。

  6. 如果master判斷slave的上一次的master是自己時,則繼續判斷請求中的offset是否在[replication-backlog-buffer]中,如果在則說明可以進行增量複製,返回[CONTINUE],slave則得知可以進行增量複製,等待slave發來的自己缺少的那部分命令,然後執行即可。

4 命令傳播階段

當數據同步完成後,此後的時間裏主從之間維護心跳來檢查對方是否在線。

master定時向slave發送[PING]請求,如果收到slave的[PONG]響應則可知slave在線(默認10s,通過參數[repl-ping-slave-period]指定)。

slave每秒向master發送[ REPLCONF ACK ${offset} ]命令,master根據偏移量響應未同步的數據,slave收到master的響應可知master在線,並執行命令,完成主從同步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章