標籤:

Redis 複製

本文中的複製,指的是主從結構的複製。

命令:slaveof 127.0.0.1 6379

表示當前redis會成為127.0.0.1:6379的slave(從伺服器)

slaveof的實現分為兩個階段

  • 數據同步:將slave的狀態更新為master(主伺服器)的數據狀態
  • 命令傳播:master狀態被修改時,讓slave和master保持一致。

一、數據同步(sync):

1)從伺服器向主伺服器發送sync命令

2)主伺服器執行bgSave,生成rdb文件,並用一個緩衝區記錄從現在開始執行的寫命令。

3)master將rdb文件發給slave,slave載入此文件

4)master將緩衝區中的命令發給slave,slave執行以後和master狀態相同

二、命令傳播(command propagate)

同步完成後,主伺服器把執行的寫命令發給slave

這種同步機制有一個缺點。假設在命令傳播階段,主從伺服器斷開連接,那麼等雙方重新連接以後,會重新執行複製操作。這種做法非常低效,原因有以下幾點:

1)主伺服器執行bgsave,會消耗大量的CPU,內存和硬碟;

2)發送rdb文件,消耗大量帶寬

3)從伺服器載入rdb文件會發生阻塞,加重主伺服器的負擔

上述問題的解決方法是命令psync(部分重同步)。master開闢一個複製積壓緩衝區,這個緩衝區是一個FIFO的隊列,主伺服器除了將命令發給從伺服器,還寫入該緩衝區,主從伺服器都有複製偏移量replication offset(位元組的偏移量)

每個redis都有自己的run ID(40位十六進位數),當主從伺服器進行初次複製時,主伺服器會把自己的run ID發給從伺服器,從伺服器會保存起來。

等主從伺服器短線並且重連以後,從伺服器會把run ID和offset發給主伺服器,如果這個run ID和主伺服器的runID相同,那麼會嘗試部分重同步,如果缺失的數據不在緩衝區中或者run ID不同,那麼會進行完全重同步

在命令傳播階段,從伺服器會向主伺服器發送心跳(每秒一次),除了檢測主從伺服器的網路連接狀態,還告知自己的複製偏移量,如果從伺服器的offset較小,那麼補發從伺服器所缺失的部分數據。檢測命令丟失和部分重同步的區別是,前者是在主從伺服器沒有斷線時執行,而後者是在主從伺服器斷線且重連以後執行。

2017-12-26閱:

redis複製的設計菁華在於可靠性:假如斷線重連以後,那麼丟失的數據怎麼辦?

這就涉及到一個全量同步增量同步的問題。解決方案是使用緩衝區。

鳴謝:複製(Replication) - Redis 命令參考

推薦閱讀:

R語言操作redis資料庫詳解
Spring Boot使用Redis進行消息的發布訂閱
Redis源碼剖析--雙端鏈表Sdlist
Python Redis事務學習筆記

TAG:Redis |