複製的完整流程
slave node
啓動,僅僅保存master node
的信息,包括master node
的host和ip
,但是複製流程沒開始
master
host和ip
是從哪兒來的,redis.conf
裏面的slaveof
配置的
- slave node內部有個定時任務,每秒檢查是否有新的master node要連接和複製,如果發現,就跟master node建立socket網絡連接
- slave node發送ping命令給master node
- 口令認證,如果master設置了requirepass,那麼salve node必須發送masterauth的口令過去進行認證
- master node第一次執行全量複製,將所有數據發給slave node
- master node後續持續將寫命令,異步複製給slave node
數據同步相關的核心機制
指的就是第一次slave連接msater的時候,執行的全量複製,那個過程裏面你的一些細節的機制
master和slave都會維護一個offset
- master會在自身不斷累加offset,slave也會在自身不斷累加offset
- slave每秒都會上報自己的offset給master,同時master也會保存每個slave的offset
這個倒不是說特定就用在全量複製的,主要是master和slave都要知道各自的數據的offset,才能知道互相之間的數據不一致的情況
backlog
master node有一個backlog,默認是1MB大小
master node給slave node複製數據時,也會將數據在backlog中同步寫一份
backlog主要是用來做全量複製中斷候的增量複製的
master run id
info server
,可以看到master run id
如果根據host+ip定位master node,是不靠譜的,如果master node重啓或者數據出現了變化,那麼slave node應該根據不同的run id區分,run id不同就做全量複製
如果需要不更改run id重啓redis,可以使用redis-cli debug reload命令
psync
從節點使用psync從master node進行復制,psync runid offset
master node會根據自身的情況返回響應信息,可能是FULLRESYNC runid offset觸發全量複製,可能是CONTINUE觸發增量複製
全量複製
- master執行bgsave,在本地生成一份rdb快照文件
- master node將rdb快照文件發送給salve node,如果rdb複製時間超過默認的60秒(repl-timeout),那麼slave node就會認爲複製失敗,可以適當調節大這個參數
- 對於千兆網卡的機器,一般每秒傳輸100MB,6G文件,很可能超過60s
- master node在生成rdb時,會將所有新的寫命令緩存在內存中,在salve node保存了rdb之後,再將新的寫命令複製給salve node
client-output-buffer-limit slave 256MB 64MB 60
,如果在複製期間,內存緩衝區持續消耗超過64MB,或者一次性超過256MB,那麼停止複製,複製失敗- slave node接收到rdb之後,清空自己的舊數據,然後重新加載rdb到自己的內存中,同時基於舊的數據版本對外提供服務
- 如果slave node開啓了AOF,那麼會立即執行
BGREWRITEAOF
,重寫AOF
rdb生成、rdb通過網絡拷貝、slave舊數據的清理、slave aof rewrite,很耗費時間
如果複製的數據量在4G~6G之間,那麼很可能全量複製時間消耗到1分半到2分鐘
增量複製
- 如果全量複製過程中,master-slave網絡連接斷掉,那麼salve重新連接master時,會觸發增量複製
- master直接從自己的backlog中獲取部分丟失的數據,發送給slave node,默認backlog就是1MB
- msater就是根據slave發送的psync中的offset來從backlog中獲取數據的
heartbeat
- 主從節點互相都會發送heartbeat信息
- master默認每隔10秒發送一次heartbeat,salve node每隔1秒發送一個heartbeat
異步複製
- master每次接收到寫命令之後,現在內部寫入數據,然後異步發送給slave node