概述
?本文概要性的介紹了Redis主從復制原理,及新舊版本主從復制的區別,優缺點。具體的主從復制過程可詳見「Redis主從復制原理二 之 主從復制工作流程」
舊版主從復制的實現
?Redis的復制功能分為 同步(sync)和 命令傳播(command propagate)兩個操作:
1)同步操作:作用于將從服務器的數據庫狀態更新至主服務器當前所處的數據庫狀態。
2)命令傳播:作用于在主服務器的數據庫狀態被修改,導致主從服務器的數據庫狀態出現不一致時,讓主從服務器的數據庫重新回到一致狀態。
同步操作
?當客戶端向從服務器發送SLAVEOF命令,要求從服務器復制主服務器時,從服務器首先需要執行同步操作,即,將從服務器的數據庫狀態更新至主服務器當前所處的數據庫狀態。
?從服務器通過向主服務器發送SYNC命令來進行同步操作,SYNC命令的執行步驟如下:
1)從服務器向主服務器發送SYNC命令。
2)收到SYNC命令的主服務器執行BGSAVE命令,在后臺生成一個RDB文件,并使用一個緩沖區記錄從現在開始執行的所有寫命令。
3)當主服務器的BGSAVE命令執行完畢時,主服務器會將BGSAVE命令生成的RDB文件發送給從服務器,從服務器接受并載入這個RDB文件,將自己的數據庫狀態更新至主服務器執行BGSAVE命令時的數據庫狀態。
4)主服務器將記錄在緩沖區里面的所有寫命令發送給從服務器,從服務器執行這些寫命令,將自己的數據庫狀態更新至主服務器數據庫當前所處的狀態。
命令傳播
?同步操作執行完畢后,主從服務器兩者的數據庫狀態達到了一致狀態,但每當主服務器執行完客戶端發送的寫命令時,主從服務器的數據庫狀態將不一致。
?為了讓主從服務器再一次回到一致狀態,主服務器需要對從服務器執行命令傳播操作:主服務器將自己執行的寫命令,發送給從服務器執行,使主從服務器保持一致狀態。
舊版復制功能的缺陷
Redis 2.8以前,從服務器對主服務器的復制可以分為如下兩種情況:
1)初次復制:從服務器以前沒有復制過任何主服務器,或從服務器當前要復制的主服務器和上一次復制的主服務器不同。
2)斷線后重復制:處于命令傳播階段的主從服務器因為網絡原因而中斷了復制,但從服務器通過自動重連重新連接上了主服務器,并繼續復制主服務器。
?缺陷在于:斷線重連后,從服務器將從新執行一遍初次復制的過程,發送SYNC命令給主服務器,主服務器執行BGSAVE命令生成RDB文件,同時將在此期間新執行的寫命令加入緩沖區,當RDB文件生成完畢,將文件發送給從服務器,而后將緩沖區中新增的命令發送給從服務器,自此主從同步完成。
?SYNC命令:一個非常耗資源的操作
1)主服務器需要執行BGSAVE命令來生成RDB文件,這個生成操作會耗費主服務器大量的CPU、內存和磁盤I/O資源。
2)主服務器需要將自己生成的RDB文件發送給從服務器,這個發送操作會耗費主從服務器大量的網絡資源(帶寬和流量),并對主服務器響應請求命令的時間產生影響。
3)接收到RDB文件的從服務器需要載入主服務器發來的RDB文件,并且在載入期間,從服務器會因為阻塞而沒辦法處理命令請求。
?所以Redis有必要保證在真正有需要時才執行SYNC命令。
新版復制功能
?為了解決舊版本復制功能在處理斷線重復制情況時的低效問題,Redis從2.8版本開始,使用PSYNC命令代替SYNC命令來執行復制時的同步操作。
PSYNC命令
?PSYNC命令具有完整完整重同步(full resychronization)和部分重同步(partial resychronization)兩種模式:
1)完整重同步:用于處理初次復制情況:完整重同步執行步驟和SYNC命令的執行步驟基本一致。都是通過讓主服務器執行BGSAVE命令生成RDB文件,并發送,以及向從服務器發送保存在緩沖區里面的寫命令來進行同步。
2)部分重同步:用于處理斷線重連后同步復制:當從服務器在斷線后重新連接主服務器時,如果條件允許,主服務器可以將主服務器連接斷開期間執行的寫命令發送給從服務器,從服務器只要接受并執行這些命令,就可以將數據庫更新至主服務器當前所處的狀態。