Redis 的主從同步(復制)
Redis 的主從同步(復制)
什么是主從同步(復制)
假設有兩個 redis 實體 ⇒ A 和 B
B 實體的內容與 A 實體的內容保持同步
那么稱 A 實體是主資料庫,B 實體是從資料庫
這個程序稱為主從同步
為什么要使用主從同步(復制)
- 防止發生單點故障
- 擴展記憶體
如何開啟/關閉主從同步
開啟同步
- 組態檔中加入
slaveof 主資料庫地址 主資料庫埠- 在命令列中執行上述命令
redis> slaveof 主資料庫地址 主資料庫埠- 在開啟從服務器時執行命令
$ reids-server --port 6380 --slaveof 主資料庫地址 主資料庫埠關閉同步,并成為主資料庫
redis> slaveof no one原理(實作)
復制分為連接建立,資料同步(sync)和命令傳播(command propagate)三個階段
連接建立這里不說,與復制原理無關
下面主要講資料同步與命令傳播兩個階段
redis 從 2.8 版本之后優化了復制功能,咱們先從舊版本的復制說起:
舊版復制程序
| 步驟 | 主服務器 | 從服務器 |
|---|---|---|
| 同步流程 | ||
| 1 | 向主服務器發送 SYNC 命令 | |
| 2 | 收到 SYNC 命令,執行 BGSAVE 生成 RDB 檔案 | |
| 3 | 使用緩沖區記錄從現在的寫命令 | |
| 4 | 將生成的 RDB 檔案發送給從服務器 | |
| 5 | 將緩沖區內的寫命令發給從服務器 | 接收并載入 RDB 檔案 |
| 6 | 接收并執行主服務器發送來的寫命令 | |
| 命令傳播流程 | ||
| 1 | 發送客戶端發過來的寫命令 | |
| 2 | 執行主服務器發送過來的寫命令 | |
| 斷線重連 | 與同步流程一致 | 與同步流程一致 |
經過上述步驟之后主從服務器的狀態可以始終保持一致,
細心的讀者已經發現了舊版復制的一些問題:
斷線重連需要重新走一次同步的流程,而同步流程中的主服務器生成 RDB 檔案和從服務器執行 RDB 檔案都是特別密集的 IO 操作,這會讓斷線重連的成本很高
于是從 2.8 版本之后,redis 使用了新的技術來防止重新執行同步流程
新版復制程序
| 步驟 | 主服務器 | 從服務器 |
|---|---|---|
| 完整同步流程 | ||
| 1 | 向主服務器發送 PSYNC 命令 | |
| 2 | 收到 PSYNC 命令,執行 BGSAVE 生成 RDB 檔案 | |
| 3 | 使用緩沖區記錄從現在的寫命令 | |
| 4 | 接收并執行主服務器發送來的寫命令 | |
| 5 | 將緩沖區內的寫命令發給從服務器 | 接收并載入 RDB 檔案 |
| 6 | 將生成的 RDB 檔案發送給從服務器 | |
| 命令傳播流程 | ||
| 1 | 發送客戶端發過來的寫命令 | |
| 2 | 執行主服務器發送過來的寫命令 | |
| 斷線重連程序 | ||
| 1 | 發送 PSYNC 命令 | |
| 2 | 向從服務器發送斷執行緒序中的寫命令 | |
| 3 | 執行寫命令 |
新版復制經過上述步驟,也可以實作主從資料庫狀態的一致,
在斷線重連程序中,只需要重新執行斷執行緒序中未同步的命令即可,這樣就比舊版的復制節省了很多 IO 操作
那么這個斷線重連的是怎么實作的呢?
部分重同步(斷線重連)的實作
redis 的部分重同步借助了4個變數:
- 服務器的運行 ID (run ID)
- 當實體重啟時,會生成40個隨機的十六進制字符
- 主服務器的復制積壓緩沖區(replication backlog)
- 主服務器每將一個命令傳送給從資料庫,都會將命令放到一個積壓佇列(固定長度的回圈佇列)中
- 主服務器的復制偏移量(replication offset)
- 主服務器將命令放到積壓佇列中時,會記錄下當前命令的偏移量,并發送給從服務器
- 從服務器的復制偏移量
- 從服務器接收到主服務器發送過來的命令與偏移量
也許將這4個變數列出來之后,有讀者就可以直接想象出來是怎么實作的了,對,沒錯,就是這么實作的
程序:
部分重同步流程
| 步驟 | 主服務器 | 從服務器 |
|---|---|---|
| 1 | 發送命令 PSYNC 主資料庫的運行ID 斷開前最新的命令偏移量 | |
| 判斷 1. 運行ID是否能夠對應 2. 斷開前最新的命令偏移量是否在佇列中 滿足上述條件可以執行部分重同步,否則執行完全同步 | ||
| 2 | 發送給從資料庫偏移量之后的命令 | |
| 3 | 執行命令 |
總結
redis 在很多細節上優化了性能,主從同步(復制)的優化只是其中的一方面,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/40069.html
標籤:NoSQL
下一篇:Falling back to java on path. This behavior is deprecated
