標籤:導致 set nc命令 初始 連接埠 利用 接受 在伺服器 沒有
一. 概念 在主從複製中,資料庫分為兩類,一類是主庫(master),另一類是同步主庫資料的從庫(slave)。 主庫可以進行讀寫操作,當寫操作導致資料變化時會自動同步到從庫。而從庫一般是唯讀(特定情況也可以寫,通過參數slave-read-only指定),並接受來自主庫的資料, 一個主庫可擁有多個從庫,而一個從庫只能有一個主庫。二. 配置方式2.1 用戶端命令
在從伺服器上執行 slave masterIP masterPort;
2.2 設定檔
在設定檔中配置 slaveof <masterip> <masterport>;除了IP和連接埠資訊外,還可以配置其他主從資訊;
三. 舊版複製功能的實現(Redis2.8以前的版本)
slave 向 master 發送 slaveof 命令後,slave先進行同步操作,再進行命令傳播;
Redis的複製功能主要分為同步(sync)和命令傳播(command propagate)兩個操作;
先通過同步將master和slave的資料庫狀態達到一致,然後通過命令傳播即時的將master的變化同步到slave;
同步:將 slave 的狀態更新為和 master 一樣的狀態;
命令傳播:master 被修改時將變化即時的同步到 slave;
3.1 同步
- slave向master發送sync命令;
- master收到sync命令後先執行bgsave命令,後台產生一個RDB檔案,同時用一個緩衝區記錄從現在開始執行的寫命令;
- master將產生的RDB檔案發送給slave;
- 將緩衝區的寫命令發送給slave;
3.2 命令傳播
同步操作執行完畢後,master將自己執行的寫命令發送給slave,slave執行命令,master和slave保持一致;
3.3 舊版複製功能的缺陷
複製的兩種情況:
初次複製:slave沒有複製過任何主伺服器,或者複製的主伺服器和上次的不同;
斷線後複製:命令傳播階段的master和slave斷連,重新串連後重新複製(先進行同步,再進行命令傳播),效率較低;
3.4 sync命令非常消耗資源
- maser執行bgsave,好肥大量的CPU,記憶體和IO資源;
- RDB檔案傳輸耗費網路資源;
- slave載入RDB檔案時發生阻塞;
4. 新版複製功能的實現(Redis2.8版本開始)
為瞭解決斷線後複製的低效問題,Redis2.8版本開始使用PSYNC命令代替SYNC命令;
4.1 PSYNC的兩種模式
- 完整重同步:用於初次複製的情況。和sync命令一樣,master建立RDB檔案,在緩衝區儲存之後的寫命令,然後發送給slave;
- 部分重同步:用於斷連後重複製的情況。master和slave斷連後重建立立串連,如果條件允許,master可以只將斷連期間的寫命令發送給slave,這樣也可以完成同步,而且效率很高。
4.2 部分重同步的實現
部分重同步主要由以下三個部分構成:
- master和slave的複製位移量;
- master的複製積壓緩衝區;
- 伺服器的運行ID;
重連後slave將自己的位移量發送給master,master就知道slave需要同步哪些資料。至於是完整重同步還是部分重同步則根據slave的複製位移量和積壓緩衝區的關係進行選擇;
4.2.1 複製位移量
master和slave各自維持一個複製位移量。根據位移量即可判斷master和slave是否一致。
master每次想slave傳播N個位元組,就將自己的複製位移量+N;
slave每次收到N個位元組,就將自己的複製位移量+N;
4.2.2 複製積壓緩衝區
複製積壓緩衝區是由master維護的一個固定長度的先進先出隊列,預設在1MB。用於儲存一定數量最新的寫命令。
master將命令傳播給slave時,還會將命令寫入複製積壓緩衝區裡面;
重連後master收到的slave的複製位移量在複製積壓緩衝區中,表明需要同步的資料全部可以再複製積壓緩衝區中取到,則進行部分重同步;否則進行完全重同步。
合理的設定複製積壓緩衝區的大小可以有效利用部分重同步模式;
大小公式:緩衝區大小 = 斷連時間秒數 * 每秒的寫命令;
4.2.3 伺服器運行ID
每個Redis伺服器都有自己的運行ID,它在伺服器啟動時產生,由40個隨機的16進位字元組成。
初次複製時,master將自己的運行ID發送給slave並儲存;
master和slave斷線重連後,slave將儲存的master運行ID發送給當前串連的主伺服器。
發送的ID和當前主伺服器ID一致則嘗試進行部分重同步,否則進行完整重同步;
4.3 PSYNC命令的實現
- slave沒複製過任何master或者執行過 slaveof no one:slave發送PSYNC ? -1命令,請求完整重同步;
- slave複製過master:slave發送 PSYNC <runid> <offset>,master自己判斷進行何種同步;
- master 返回 +FULLRESYNC <runid> <offset> 回複,則進行完整重同步,slave儲存這個 runid,並將該 offset 作為自己的初始化 offset;
- master 返回 +CONTINUE 回複,則進行部分重同步,slave等待資料即可;
- master 返回 - ERR,表示master版本低於2.8;則slave發送 SYNC 命令,進行完整重同步;
5. 複製的實現
Redis主從複製