redis——新版复制
sync雖然解決了數據同步問題,但是在數據量比較大情況下,從庫斷線從來依然采用全量復制機制,無論是從數據恢復、寬帶占用來說,sync所帶來的問題還是很多的。于是redis從2.8開始,引入新的命令psync。
psync有兩種模式:完整重同步和部分重同步。
部分重同步主要依賴三個方面來實現,依次介紹。
offset(復制偏移量):
主庫和從庫分別各自維護一個復制偏移量(可以使用info replication查看),用于標識自己復制的情況:
在主庫中代表主節點向從節點傳遞的字節數,在從庫中代表從庫同步的字節數。
每當主庫向從節點發送N個字節數據時,主節點的offset增加N
從庫每收到主節點傳來的N個字節數據時,從庫的offset增加N。
因此offset總是不斷增大,這也是判斷主從數據是否同步的標志,若主從的offset相同則表示數據同步量,不通則表示數據不同步。
replication backlog buffer(復制積壓緩沖區):
復制積壓緩沖區是一個固定長度的FIFO隊列,大小由配置參數repl-backlog-size指定,默認大小1MB。
需要注意的是該緩沖區由master維護并且有且只有一個,所有slave共享此緩沖區,其作用在于備份最近主庫發送給從庫的數據。
在主從命令傳播階段,主節點除了將寫命令發送給從節點外,還會發送一份到復制積壓緩沖區,作為寫命令的備份。
?
除了存儲最近的寫命令,復制積壓緩沖區中還存儲了每個字節相應的復制偏移量,由于復制積壓緩沖區固定大小先進先出的隊列,所以它總是保存的是最近redis執行的命令。
所以,重連服務器后,從服務器會發送自己的復制偏移量offset給主服務器,
如果offset偏移量之后的數據仍然存在于復制擠壓緩沖區,就執行部分重同步操作。
相反,執行完整重同步操作。
run_id(服務器運行的唯一ID)?
每個redis實例在啟動時候,都會隨機生成一個長度為40的唯一字符串來標識當前運行的redis節點,查看此id可通過命令info server查看。
當主從復制在初次復制時,主節點將自己的runid發送給從節點,從節點將這個runid保存起來,當斷線重連時,從節點會將這個runid發送給主節點。主節點根據runid判斷能否進行部分復制:
- 如果從節點保存的runid與主節點現在的runid相同,說明主從節點之前同步過,主節點會更具offset偏移量之后的數據判斷是否執行部分復制,如果offset偏移量之后的數據仍然都在復制積壓緩沖區里,則執行部分復制,否則執行全量復制;
- 如果從節點保存的runid與主節點現在的runid不同,說明從節點在斷線前同步的redis節點并不是當前的主節點,只能進行全量復制;
?
psync流程:
復制
客戶端向服務器端發送:SLAVEOF
1、設置主服務器的地址和端口
存到masterhost和mastterport兩個屬性里之后,向客戶端發送ok,然后開始復制工作。
2、建立套接字鏈接
從服務器根據命令設置的地址和端口,創建鏈接,并且為這個套接字創建一個專門處理復制工作的文件事件處理器。
主服務器也會為套接字創建相應的客戶端狀態,并且把從服務器當作一個客戶端來對待。
3、發送ping命令(檢查)
檢查套接字狀態是否正常
檢查主服務器是否能正確處理請求。(如果不能,就重連)
4、身份認證
?
5、發送端口信息
從服務器向主服務器發送信息,主服務器記錄。
6、同步
從服務器向主服務器發送psync命令。(主服務器也成為從服務器的客戶端,因為主服務器會發送寫命令給從服務器)
7、命令傳播
完成同步后,進入傳播階段,主服務器一直發送寫命令,從服務器一直接受,保證和主服務器一致。
心跳檢測
默認一秒一次,從服務器向主服務器發送命令:REPLCONF ACK <offset>
三個作用:
檢測網絡連接狀態:如果主服務器一秒沒收到命令,就說明出問題了
輔助實現min-slaves配置:min-slaves-to-write 3? ?min-slaves-max-log 10:當從服務器小于3個或延遲都大于10,主服務器拒絕寫命令。
檢測命令丟失:如果命令丟失,主服務器會發現偏移量不一樣,然后它就會根據偏移量,去積壓緩沖區找到缺少的數據并發給從服務器。
總結
以上是生活随笔為你收集整理的redis——新版复制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UNIX(进程间通信):16深入理解So
- 下一篇: leetcode122. 买卖股票的最佳