2021年了,Redis複製原理你應該理解!



感謝關注趣學程序!公衆號內部回覆666獲取熱門教程




本文來源:http://r6d.cn/YFur



Redis的單機模式不難,配置文件參數瞭解具體含義,設定業務上符合自己的就好了。

之前記錄了關於Redis的數據結構和對象的知識(可以點Redis標籤看看),下面開始填坑。


複製

在Redis中,用戶可以通過執行 SLAVEOF 命令或者設置 slaveof 選項,讓一個服務去複製(replicate)另一個服務器。被複制的服務器爲主服務器(master),另一個對主服務器進行復制的服務器則被稱爲從服務器(slave)

舉個🌰:(Redis版本是4.0.8)

在6379端口啓動一個redis-server:
$ redis-server --port 6379
$ redis-cli -p 6379
127.0.0.1:6379> 



在6380端口號啓動一個redis-server,接着通過slaveof命令進行復制
$ redis-server --port 6380
$ redis-cli -p 6380
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK

在這裏,6379 是主服務器,6380 是從服務器。

接着能在 6380 的 redis-server 界面中看到日誌:

19092:S 23 Mar 01:00:26.944 * Before turning into a slave, using my master parameters to synthesize a cached master: I may be able to synchronize with the new master with just a partial transfer.
19092:S 23 Mar 01:00:26.945 * SLAVE OF 127.0.0.1:6379 enabled (user request from 'id=2 addr=127.0.0.1:60778 fd=8 name= age=50 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof')
19092:S 23 Mar 01:00:27.234 * Connecting to MASTER 127.0.0.1:6379
19092:S 23 Mar 01:00:27.234 * MASTER <-> SLAVE sync started
19092:S 23 Mar 01:00:27.234 * Non blocking connect for SYNC fired the event.
19092:S 23 Mar 01:00:27.246 * Master replied to PING, replication can continue...
19092:S 23 Mar 01:00:27.246 * Trying a partial resynchronization (request 2e56cf1343f6b2e864c968bd59b4a16ed78b8f1d:1).
19092:S 23 Mar 01:00:27.266 * Full resync from master: bf36b20c3942e91ac4f262a2afdc90970b2d7c54:0
19092:S 23 Mar 01:00:27.266 * Discarding previously cached master state.
19092:S 23 Mar 01:00:27.441 * MASTER <-> SLAVE sync: receiving 187 bytes from master
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Flushing old data
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Loading DB in memory
19092:S 23 Mar 01:00:27.442 * MASTER <-> SLAVE sync: Finished with success

具體流程如下:

  • 從服務器發送 SYNC 命令到主服務器
  • 主服務器通過 BGSAVE(子線程中運行)生成 RDB 文件,發送給從服務器
  • 主服務器在 BGSAVE 過程中的寫操作,保存在緩衝區中,發送給從服務器

進行復制中的主從服務器雙方的數據庫將保存相同的數據,概念上將這種現象稱爲“數據庫狀態一致”,或者簡稱“一致”。


舊版複製功能的缺陷(舊版指的是2.8之前)

在Redis中,從服務器對主服務器的複製可以分成兩種情況:

  • 初次複製:從服務器從前沒有複製過任何主服務器,或者從服務器當前要複製的主服務器和上一次複製的主服務器不同。
  • 斷線後重新複製:處於命令傳播階段的主從服務器因爲網絡原因而中斷了複製,但從服務器通過自動重連接重新連上了主服務器,繼續複製主服務器。

對於初次複製來說來說,舊版複製完全沒有問題,但是斷線重連之後,如果當時從服務器已經複製了一些,重連之後,從服務器需要重新複製,造成一些浪費。

舊版使用的是SYNC命令進行復制,是一個非常浪費資源的操作。


新版複製的優勢

使用 PSYNC 命令替代 SYNC 命令來執行復制時的同步操作。

具有完整重同步(full resynchronization)部分重同步(partial resynchronization)兩種模式:

  • 完整重同步:與初次複製相同,都是先讓主服務器發送 RDB 文件,以及向從服務器發送保存在緩衝區裏面的命令來進行同步。
  • 部分重分步:當從服務器斷線的時候,下次可以發起 PSYNC 命令,從中斷處開始,執行部分重同步,只需要將從服務器缺少的寫命令發送給從服務器執行就可以了,這時使用的資源比起執行 SYNC 命令所需的資源要少的多。

新版複製實現

部分重同步功能由以下三個部分構成:

  • 主服務器的複製偏移量(replication offset)和從服務器的複製偏移量

    主從服務器都各自持有一份複製偏移量。如果偏移量一致,表示處於一致狀態;否則,兩者處於不一致狀態。

  • 主服務器的複製積壓緩衝區((replication backlog)

    複製積壓緩衝區是由主服務器維護的一個固定長度(fixed-size)先進先出(FIFO)隊列,默認是1MB。

    主服務器的複製積壓緩衝區裏面會保存着一部分最近傳播的寫命令,並且複製積壓緩衝區會爲隊列中的每個字節記錄相應的複製偏移量。

    當從服務器重新連上主服務器時,從服務器會通過PSYNC命令將自己的offset發送給主服務器,主服務器會根據這個複製偏移量來決定對從服務器執行何種同步操作。

  • 服務器的運行ID(run ID)

    每個服務器都有自己的運行 ID,在服務器啓動時自動生成,由 40 個堆積的十六進制字符組成。

    當從服務器對主服務器進行初次複製時,主服務器會將自己的運行ID傳送給從服務器,而從服務器則會將這個運行ID保存起來。

    • 斷線重連後,如果從服務器保存的運行 ID 與當前鏈接的主服務器的運行 ID 相同,主服務器會嘗試執行 部分重同步操作
    • 相反的,如果不一致,主服務器將對從服務器執行 完整重同步操作

PSYNC命令實現

具體調用看流程圖即可:


心跳檢測

在命令傳播階段,從服務器默認會以每秒一次的頻率,向主服務器發送命令:

$ REPLCONF ACK <replication_offset>

其中replication_offset是從服務器當前的複製偏移量。發送REPLCONF ACK有三個作用:

  • 檢測主從服務器的網絡連接情況
  • 輔助實現min-slaves選項
  • 檢測命令丟失

小結:

  • 部分重同步通過 複製偏移量、複製積壓緩衝區、服務器運行 ID三個部分來實現。
  • 在複製操作剛開始的時候,從服務器會成爲主服務器的客戶端,並通過向主服務器發送命令請求來執行復制步驟,而在複製操作的後期,主從服務器互相成爲對方的客戶端。
  • 主服務器通過向從服務器傳播命令來更新從服務器的狀態,保持主從服務器一致,而從服務器則通過向主服務器發送命令來進行心跳檢測,以及命令丟失檢測。

往期推薦


爲什麼建議使用你 LocalDateTime ,而不是 Date?

如何給妹子優化 Windows ?

Windows 10 全新界面來了:煥然一新!

edge 81版本瀏覽器插件安裝教程

人人都能讀懂的編譯器原理

有個程序員老公有多爽???

乾貨:一文讀懂客戶端請求是如何到達服務器的

“91系列”資源網涼了,500餘網站被封殺!



 
由於微信公衆號近期改變了推送規則,如果你想如常看到我們的文章,可以時常點擊文末右下角的「 在看 」;或者將 趣學程序 星標。

這樣操作後,我們每次新的推送才能第一時間出現在你的訂閱列表中~




掃描二維碼

獲取更多精彩

趣學程序






本文分享自微信公衆號 - 趣學程序(quxuecx)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章