在Redis中,用戶可以通過執行SALVEOF命令,讓一個服務器去復制另一個服務器,
127.0.0.1:12345> SLAVEOF 127.0.0.1 6379
OK
- 6379的奴隸是12345,
舊版復制功能實作
Redis的復制功能分為同步(sync)和命令傳播兩個操作:
- 同步:將從服務器更新為主服務器的狀態,
- 命令傳播:在主服務器狀態被修改,導致主從狀態不一致,讓主從回到一致狀態,
同步
客戶端向服務器發送SYNC命令,SYNC步驟:
- 從 -> 主 發送SYNC,
- 主 執行BGSAVE命令,后臺生成RDB,并且使用緩沖區記錄 從 現在開始執行的所有寫命令,
- RDB生成完畢時,發送給 從,從 載入這個RDB,更新至 主 執行BGSAVE時的資料庫狀態,
- 主 將緩沖區的寫命令發給 從,從 更新至 主 當前的狀態,
命令傳播
在同步執行完畢之后,主從達到一致狀態,但是當 主 執行客戶端的命令時,主從再次不一致,
為了讓主從再次回到一致狀態,主 需要對 從 執行命令傳播操作:主 會將自己執行的寫命令發送給 從 ,這樣就回
到主從一致了(迫真),
舊版復制的缺陷
對于第一次復制來說舊版是可以的,但是對于斷線后重連效率是很低的,因為,斷線重連的服務器保存的資料大部
分是相同的,發送SYNC命令傳送RDB檔案并不是非做不可的!
SYNC命令是一個非常耗費資源的操作,
新版復制功能的實作
為了解決舊版的問題,Redis從2.8開始,使用PSYNC代替SYNC,
PSYNC有完整重同步和部分重同步2個命令:
-
完整重同步:與同步命令是一樣的,
-
部分重同步:如果條件允許,主 可以將主從服務器連接斷開期間執行的寫命令發送給 從,
部分重同步的實作
部分重同步由以下三個部分構成:
-
主服務器的復制偏移量(replication offset)和從服務器的復制偏移量,
-
主服務器的復制積壓緩沖區(replication backlog),
-
服務器的運行ID(run ID),
復制偏移量

A斷線后,從服務器向主服務器發送PSYNC,報告A的offset為10086,
復制積壓緩沖區
緩沖區由主服務區維護的固定長度先進先出(fixed-size FIFO)佇列,默認大小為1MB,
當主服務器進行命令傳播時,不僅會將命令發送給從服務器,還會將寫命令入隊到緩沖區中,
因此,主服務器的緩沖區保存著最近傳播的寫命令,并且記錄了每個位元組的偏移量,
當從服務器重新連上主服務器,從服務器發送自己的offset,主服務器根據這個offset決定執行何種操作:
- 如果offset之后的資料仍然存在于緩沖區里,那么主服務器將對從服務器執行部分重同步,
- 相反如果不存在于緩沖區里,那么執行完整重同步,
根據需要調整復制積壓緩沖區大小
最小大小計算公式:second * write_size_per_second
second為從服務器重新連上主服務器的平均時間,
write_size_per_second是主服務器平均每秒產生的寫命令資料量,
服務器運行ID
每個服務器運行后會自動生成40個隨機十六進制字符的ID,
-
主 和 從 初次復制時,主 會將自己的ID給 從,
-
當從服務器斷線并重新連上主服務器時,從服務器會發送之前保存的ID給 主,如果一致就可以部分重同步,
復制的實作
-
設定主服務器的地址和埠
-
建立套接字連接
-
發送PING
-
身份驗證
-
發送埠資訊
-
同步
值得一提的是,在同步之前,只有 從 是 主 的客戶端,同步之后,主 也是 從 的客戶端,主從服務器雙方都是對方
的客戶端,他們才可以互相發送命令,主 才可以發送寫命令改變 從 的資料庫狀態,
- 命令傳播
Reference
《Redis設計與實作》
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/304235.html
標籤:其他
上一篇:Hive語法及其進階(二)
