Redis学习之复制(三)
復制
復制的難點在同步階段,讓我們先了解同步的實現:
1.同步的實現
概念:讓從服務器的狀態更新到與主服務器一致。
舊版的同步實現
舊版的同步操作是通過SYNC命令來完成的,執行步驟為:
- 從服務器向主服務器發送SYNC命令。
- 主服務器收到SYNC命令之后,主服務器會執行BGSAVE命令,然后在后臺生成一個RDB持久化文件,并用一個重寫緩存區記錄從現在開始的所有寫命令。
- 當主服務器的BGSAVE命令執行完之后,主服務器會將BGSAVE命令生成的RDB文件發送給從服務器,從服務器會接收并載入這個RDB文件,將自己的數據庫更新至主服務器執行BGSAVE命令時的數據庫狀態,將自己的數據庫更新至主服務器執行BGSAVE命令這一刻的狀態。
- 主服務把重寫緩存器的寫命令發送給從服務器,讓從服務器恢復到主服務的最新狀態。
缺陷:同步分成兩種情況,初次復制和斷線后復制,如果是初次復制,用RDB文件復制的方法沒有什么問題,但如果是斷線復制的情況,主服務器和從服務器的數據相差無幾,如果也執行RDB文件恢復未免代價也太大了!
新版的同步實現
為了解決斷線復制方法的低效問題,Redis2.8用PSYNC命令代替了SYNC命令。
PSYNC有完整重同步和部分重同步的模式:
- 完整重同步解決的是初次復制的情況,用RDB持久化文件實現。
- 部分重同步解決的是斷線后重復的情況,主服務器只需要把斷線階段的寫命令發送給從服務器即可。
首先了解幾個概念:
- 復制偏移量:主從服務器都會維護復制偏移量,記錄當前的數據長度。
- 復制擠壓緩存區:固定長度的先進先出的隊列,記錄主服務器的最新寫命令。
- 服務器運行id:相當服務器的編號,主服務器在初次復制時會把自己的id發送給從服務器。
部分重同步的實現:
首先從服務器發送自己的復制偏移量給主服務,主服務器把這個復制偏移量與自身的復制偏移量對比,然后查看自己的復制擠壓緩存中是否還保留著這部分數據,如果保留著,那么只需要把這個部分的數據發送給從服務器就行,否則執行完全重同步。
2.復制的實現
步驟一:設置主服務器的地址和端口
當客戶端向從服務器發送以下命令時:
SLAVEOF 127.0.0.1 6379
從服務器會把這個主服務器的ip和端口保存起來:
struct redisServer{//主服務器地址char *masterhost;//主服務器端口int masterport; }步驟二:建立套接字連接
從服務器根據自己設置的IP地址和端口,來創建連接主服務器的套接字。
步驟三:發送ping命令
創建完套接字之后,從服務器發送一個ping命令給主服務器,為了檢查主服務器是否能正常處理命令 和 檢查他的讀寫狀態是否正常。
發送命令之后會遇到三種情況:
步驟四:身份驗證
從服務器收到PONG回復之后,下一步就是決定是否進行身份驗證。
負責驗證身份的從服務器是masterauth選項,主服務器是requirepass選項。身份驗證有三種情況:
步驟五:發送端口信息
從服務器向主服務器發送從服務器的監聽端口號。
typedef struct redisClient{//從服務器的監聽端口號int slave_listening_port; }步驟六:同步
從服務器將向主服務器發送PSYNC命令執行同步操作,把自己的數據庫更新到主服務器數據庫當前所處的狀態。
步驟六:命令傳播
當完成了同步之后,主從服務器就會進入命令傳播階段,這時主服務器只要一直將自己執行的寫命令發送給從服務器,而從服務器只要一直接收并執行主服務器發來的寫命令,就可以保證主從服務器的一致性。
步驟七:心跳檢測問題
在命令傳播階段,從服務器還會默認以每秒一次的頻率,向主服務器發送心跳命令,來檢測主從服務器的網絡連接狀態。
總結
以上是生活随笔為你收集整理的Redis学习之复制(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis学习之单机数据库(二)
- 下一篇: Redis学习之Sentinel(四)