完整復(fù)制流程
(1)slave node 啟動,僅僅保存master node的信息,包括master node的host和ip,但是復(fù)制還沒有開始。master host和ip從redis.conf里邊配置的。
(2)slave node內(nèi)部有定時任務(wù),每秒檢查是否有新的master node要連接和復(fù)制,如果發(fā)現(xiàn)就和master node建立socket網(wǎng)絡(luò)連接。
(3)slave node發(fā)送ping命令給master node。
(4)口令認證,如果master設(shè)置了requirepas,那么salve node必須發(fā)送masterauth的口令過去進行認證。
(5)master node第一次執(zhí)行全量復(fù)制,將所有數(shù)據(jù)發(fā)送給slave node。
(6)master node后續(xù)持續(xù)將寫命令,異步復(fù)制給slave node。
數(shù)據(jù)同步相關(guān)核心機制
第一次slave連接master的時候,執(zhí)行全量復(fù)制,這個過程中存在一些細節(jié)機制。
(1)master和slave都會維護一個offset
master會在自身不斷累加offset,slave會在自身不斷累加offset。
slave每秒會上報自己的offset給master,同時master會保存每個slave的offset。
(2)backlog
master node有一個backlog,默認1MB大小
master node給slave node復(fù)制數(shù)據(jù)時,也會將數(shù)據(jù)在backlog中同步寫一份。
backlog主要是用來做全量復(fù)制中斷后的增量復(fù)制。
(3)master run id
info server,可以看到master run id
如果根據(jù)host+ip定位master node,是不靠譜的,如果master node重啟或者數(shù)據(jù)出現(xiàn)變化,那么slave node應(yīng)該根據(jù)不同的run id區(qū)分,run id 不同就做全量復(fù)制。
如果需要不更改run id重啟redis,可以使用redis-cli debug reload命令。
全量復(fù)制
- master 執(zhí)行bgsave,在本地生成一份rdb快照文件。
- master node將rdb快照文件發(fā)送給salve node,如果rdb復(fù)制時間超過60秒(repl-timeout),那么slave node就會認為復(fù)制失敗,可以適當(dāng)調(diào)節(jié)大這個參數(shù)。
- 對于千兆網(wǎng)卡,一般每秒傳輸100MB,6G文件,很可能超過60秒。
- master node在生成rdb時,會將所有新的寫命令緩存到內(nèi)存中,在salve node中保存了rdb之后,再將新寫的命令復(fù)制給salve node。
- client-output-buffer-limit slave 256MB 64MB 60,如果在復(fù)制期間,內(nèi)存緩沖區(qū)持續(xù)消耗超過64MB,或者一次性超過256MB,那么停止復(fù)制,復(fù)制失敗。
- slave node接收到rdb之后,清理自己的舊數(shù)據(jù),然后重新加載rdb到自己的內(nèi)存中,同時基于舊數(shù)據(jù)版本對外提供服務(wù)。
- 如果slave node開啟了AOF,那么會立即執(zhí)行重寫AOF
rdb生成,rdb通過網(wǎng)絡(luò)拷貝,slave舊數(shù)據(jù)的清理,slave aof rewrite,很耗費時間,如果復(fù)制的數(shù)據(jù)量在4G-6G之間,那么很可能全量復(fù)制時間消耗到1分半到2分鐘。
增量復(fù)制
- 如果全量復(fù)制過程中,master-slave網(wǎng)絡(luò)連接斷掉,那么salve重新連接master時,會觸發(fā)增量復(fù)制
- master直接從自己的backlog中獲取部分丟失數(shù)據(jù),發(fā)送給salve node,墨粉backlog就是1MB
-
master就是根據(jù)slave發(fā)送的paync中的offset來從backlog中獲取數(shù)據(jù)的
maste run id的作用.png

