:::tipredis
SLAVEOF host:port 命令能夠將當前服務器去複製目標服務器,進行復制中的主從服務器的數據庫將保存相同的數據,概念上稱爲數據庫狀態一致數據庫
:::服務器
當從服務器發送SLAVEOF
命令要求複製主服務器時,從服務器首先執行同步
操做,即將從服務器的數據庫狀態更新至主服務器當前所處的數據庫狀態,具體步驟以下網絡
SYNC
命令BGSAVE
命令,在後臺生成RDB文件,並使用緩衝區記錄從如今執行BGSAVE
以後執行的全部寫命令BGSAVE
以後,主服務器會將RDB文件發送給從服務器,從服務器接收並載入這個RDB文件同步操做完成後,主從服務器目前的數據庫狀態達到一致,但這種狀態不是一成不變的,每當主服務器執行客戶端發送的寫命令時,主從服務器的數據庫就再也不一致設計
因此爲了保持主從服務器的數據一致,主服務器須要對從服務器執行命令傳播:將寫命令發送給從服務器,當從服務也執行完後,主從服務器將再次回到一致狀態3d
舊版複製功能的缺陷主要體如今從服務器斷線重連的處理code
如上圖的狀況,從服務器在某一刻斷線,再此期間主服務器增長了k3,k4兩個鍵,按目前的實現邏輯,從服務器在以後重連後,依舊是再次發送SYNC
命令進行同步(主服務器生成和發送RDB文件給從服務器載入)cdn
但其實從服務器主須要斷線期間的k3,k4鍵便可,RDB文件中的其餘鍵信息對從服務器來講都是沒必要要的blog
:::tip隊列
SYNC是一個很是耗資源的操做
:::
爲了解決斷線重連後的重同步問題,Redis2.8之後使用了PSYNC
代替SYNC
進行同步操做,有如下兩種模式:
PSYNC ? -1
PSYNC runid offset
如下是執行部分重同步時的通訊過程
部分重同步主要由三個部分組成
每個服務器都會分別維護一個複製偏移量:
那麼經過對比主從服務器的複製偏移量就能夠知道
經過複製偏移量能夠知道主從服務器之間缺失了多少數據,那麼缺失的數據是什麼?要去哪裏找回來呢?
這裏就用上了複製積壓緩衝區了
當主服務器進行命令傳播
時,它不只將寫命令發送給全部從服務器,還會將寫命令放進一個固定長度的先進先出的隊列
裏,這個隊列就是複製積壓緩衝區(默認大小是1MB)
當從服務器重連後,從服務器經過PSYNC
命令將本身的複製偏移量發送給主服務器
複製偏移量
以後的數據還在複製積壓緩衝區
中,那麼進行部分重同步
的操做複製偏移量
以後的數據不在複製積壓緩衝區
中,那麼進行完整重同步
的操做:::tip
如何調整複製積壓緩衝區的大小
經過redis.conf中的repl-backlog-size進行調整
通常調整爲 2 * 斷線重連所需的平均秒數 * 主服務器每秒產生的寫命令數量
:::
:::tip
每一個Redis服務器都擁有本身的運行ID
運行ID由服務器啓動時生成,由40個隨機的十六進制字符組成
:::
初次複製時,從服務器會保存主服務器的運行ID
當從服務器斷線重連時,從服務器將這個運行ID發送給主服務器:
相同
,則說明斷線前複製的就是當前鏈接的主服務器,主服務器能夠根據條件嘗試進行部分重同步
不一樣
,則說明斷線前複製的不是當前鏈接的主服務器,主服務器將對從服務器進行完整重同步
:::tip
在命令傳播階段,從服務器默認一秒一次的速率,向主服務器發送指令
REPLCONF ACK <replication_offset>
其中replication_offset時從服務器當前的複製偏移量
:::
發送REPLCONF ACK命令主要由三個做用: