Redis設計與實現---複製

舊版複製實現

  • 同步:將從服務器的數據庫狀態更新至主服務器當前所處的數據庫狀態

                                       

  • 命令傳播:在主服務器的數據庫狀態被修改,導致主從服務器的數據庫狀態不一致時,讓主從服務器的數據庫重新回到一致狀態。當主服務器執行完命令之後,進行命令傳播操作,將命令發送給從服務器執行,從服務器執行了相同命令。主從服務器再次回到一致狀態。

缺陷

斷線後重複製,需同步所有數據。實際可能只是一小部分數據缺失。

新版複製實現

  • 完整重同步:通過讓主服務器創建併發送RDB文件,以及向從服務器發送保存在緩衝區裏面寫命令來進行同步

  • 部分重同步:當從服務器在斷線後重新連接主服務器時,如果條件允許,主服務器將主從服務器連接斷開期間執行的寫命令發送給從服務器。

                                 

部分重同步的實現

  • 主服務器的複製偏移量和從服務器的複製偏移量
  • 主服務器的複製積壓緩衝區
  • 服務器的運行ID

複製偏移量

執行復制雙方------主服務器和從服務器分別維護一個複製偏移量:

主服務器每次向從服務器傳播N個字節的數據時,就將自己的複製偏移量的值增加N。

從服務器每次收到主服務器傳播來的N個字節數據時,將自己的複製偏移量的值加上N。

複製積壓緩衝區

複製積壓緩衝區是由主服務器維護的一個固定長度先進先出隊列(當入隊元素大於隊列長度時,最先入隊元素會被彈出。默認大小1MB。可以根據second(斷線後重連平均時間)*write_size_per_second(平均每秒產生寫命令數據量)來估算設置repl-backlog-size選項改變緩衝區大小。

重連同步流程:

  1. 當從服務器A(上圖爲例)斷線重連後,向主服務器發送PSYNC命令,報告自己的偏移量爲10086
  2. 主服務器收到命令後,檢查偏移量10086之後的數據是否存在於複製積壓緩衝區裏。存在,向服務器發送+CONTINUE回覆,表示數據同步將以部分重同步模式進行。(不存在,主服務器將對從服務器執行完整重同步操作)
  3. 主服務器將複製積壓緩衝區10086之後的所有數據發送給從服務器
  4. 從服務器接收缺失數據,回到與主服務器一致的狀態

服務器運行ID

每個Redis服務器,不論主服務器還是從服務器,都會有自己的運行ID。從服務器在對主服務器進行初次複製時,保存該主服務器的運行ID。當斷線重連後,從服務器保存運行ID與連接的主服務器運行ID相同,可執行部分重同步。不同將執行完整重同步。

PSYNC命令流程圖

心跳檢測

在命令傳播階段,從服務器默認會以每秒一次的頻率,向主服務器發送命令:REPLCONF ACK <replication_offset>

其中replication_offset是從服務器當前的複製偏移量

  • 檢測主從服務器的網絡連接狀態
  • 輔助實現min-slaves選項。min-slaves-to-write和min-slaves-max-lag防止主服務器在不安全的情況下執行寫命令。
    min-slaves-to-write 3
    min-slaves-max-lag 10

    在從服務器數量少於3個,或者三個從服務器的延遲值(最後一次心跳檢測距離現在過了多少秒)都大於或等於10秒時,主服務器將拒絕執行寫命令

  • 檢測命令丟失。偏移量不一致,會進行補發缺失數據的操作(Redis 2.8之前會命令丟失)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章