Redis主從複製的原理
- 2019 年 10 月 3 日
- 筆記
更多內容,歡迎關注微信公眾號:全菜工程師小輝。公眾號回復關鍵詞,領取免費學習資料。
在Redis集群中,讓若干個Redis伺服器去複製另一個Redis伺服器,我們定義被複制的伺服器為主伺服器(master),而對主伺服器進行複製的伺服器則被稱為從伺服器(slave),這種模式叫做主從複製模式。
數據流向是單向的,只能是從master到slave
一個slave只能有一個master
主從複製的作用
- 為數據提供多個副本,實現高可用
- 實現讀寫分離(主節點負責寫數據,從節點負責讀數據,主節點定期把數據同步到從節點保證數據的一致性)
主從複製的方式
- 命令slaveof。
優點:無需重啟。缺點:不便於管理
// 命令行使用 slaveof ip port // 使用命令後自身數據會被清空,但取消slave只是停止複製,並不清空 - 修改配置。
優點:統一配置。缺點:需要重啟
// 配置文件中配置 slaveof ip port slave-read-only yes //只允許從節點進行讀操作 全量複製
用於初次複製或其它無法進行部分複製的情況,將主節點中的所有數據都發送給從節點,是一個非常重型的操作,當數據量較大時,會對主從節點和網路造成很大的開銷

全量複製過程:
- Redis內部會發出一個同步命令,剛開始是Psync命令,Psync ? -1表示要求master主機同步數據
- 主機會向從機發送run_id和offset,因為slave並沒有對應的 offset,所以是全量複製
- 從機slave會保存主機master的基本資訊
- 主節點收到全量複製的命令後,執行bgsave(非同步執行),在後台生成RDB文件(快照),並使用一個緩衝區(稱為複製緩衝區)記錄從現在開始執行的所有寫命令
- 主機發送RDB文件給從機
- 發送緩衝區數據
- 刷新舊的數據。從節點在載入主節點的數據之前要先將老數據清除
- 載入RDB文件將資料庫狀態更新至主節點執行bgsave時的資料庫狀態和緩衝區數據的載入。
全量複製開銷
- 主節點需要bgsave
- RDB文件網路傳輸佔用網路io
- 從節點要清空數據
- 從節點載入RDB
- 全量複製會觸發從節點AOF重寫
部分複製
部分複製是Redis 2.8以後出現的,用於處理在主從複製中因網路閃斷等原因造成的數據丟失場景,當從節點再次連上主節點後,如果條件允許,主節點會補發丟失數據給從節點。因為補發的數據遠遠小於全量數據,可以有效避免全量複製的過高開銷,需要注意的是,如果網路中斷時間過長,造成主節點沒有能夠完整地保存中斷期間執行的寫命令,則無法進行部分複製,仍使用全量複製

部分複製過程:
- 如果網路抖動(連接斷開 connection lost)
- 主機master 還是會寫 repl_back_buffer(複製緩衝區)
- 從機slave 會繼續嘗試連接主機
- 從機slave 會把自己當前 run_id 和偏移量傳輸給主機 master,並且執行 pysnc 命令同步
- 如果master發現你的偏移量是在緩衝區的範圍內,就會返回 continue命令
- 同步了offset的部分數據,所以部分複製的基礎就是偏移量 offset。
伺服器運行ID(run_id):每個Redis節點(無論主從),在啟動時都會自動生成一個隨機ID(每次啟動都不一樣),由40個隨機的十六進位字元組成;run_id用來唯一識別一個Redis節點。 通過info server命令,可以查看節點的run_id。
開發運維常見的問題
- 讀寫分離
- 複製數據存在延遲(如果從節點發生阻塞)
- 從節點可能發生故障
- 主從配置不一致
- 例如maxmemory不一致,可能會造成丟失數據
- 例如數據結構優化參數不一致:造成主從記憶體不一致
- 規避全量複製
- 第一次全量複製不可避免,所以分片的maxmemory減小,同時選擇在低峰(夜間)時,做全量複製。
- 複製積壓緩衝區不足
增大複製緩衝區配置rel_backlog_size
例如如果網路中斷的平均時間是60s,而主節點平均每秒產生的寫命令(特定協議格式)所佔的位元組數為100KB,則複製積壓緩衝區的平均需求為6MB,保險起見,可以設置為12MB,來保證絕大多數斷線情況都可以使用部分複製。
- 複製風暴
master節點重啟,master節點生成一份rdb文件,但是要給所有從節點發送rdb文件。對cpu,記憶體,頻寬都造成很大的壓力
更多內容,歡迎關注微信公眾號:全菜工程師小輝。公眾號回復關鍵詞,領取免費學習資料。
