主從複製,是把一臺redis服務器上數據複製到其餘服務器的機制,其中前者被稱爲主節點(master),後者被稱爲從節點(slave)。html
主從複製的主要主要做用:node
默認狀況下,每一個redis服務器都是master節點,每個master能夠有多個slave節點,可是一個salve節點只能有一個master節點。redis
準備節點算法
默認6380端口做爲master節點,再啓動一個6380節點做爲salve節點。服務器
複製一個配置文件,命名爲redis6380.conf網絡
配置新的端口號負載均衡
兩個redis實例已經啓動。socket
執行復制命令tcp
啓動兩個實例優化
執行slaveof命令
查看效果
master節點寫入,讀取
slave節點讀取數據
至此,複製搭建成功,數據已經成功從master複製到了slave,而且經過salve讀取成功。
直接使用slaveof no one命令便可斷開和master的複製關係
斷開復制關係後的數據
能夠看到原有的數據保留了
斷開後在原有master寫入
數據將再也不同步到6380
能夠經過切換到其餘master的方式斷開和當前master的綁定。可是和slave no one不一樣的是,切換新的master後,從原有master複製過來的數據會被清空。
一對一,一對多,樹狀結構。
4.1保存主節點
執行slaveof後從節點只是保存了主節點的地址信息變直接返回,複製流程尚未正式開始。
4.2 主從創建socket鏈接
從節點內部經過每秒運行的定時任務來處理相關邏輯,當定時任務發現存在新的主節點後,會嘗試和主節點創建網絡鏈接。
從節點會建立一個socket去鏈接主節點,後續數據同步都是基於這個socket進行。
若是從節點沒法創建鏈接,定時任務會無限重試到鏈接成功或者複製被取消爲止。
4.3 發送ping命令
鏈接創建成功後從節點會向主節點發送ping請求進行首次通訊,主要有以下目的:
發送ping命令後若是從節點沒有收到pong回覆或者超時(好比網絡超時,或者主節點阻塞沒法處理等),從節點會斷開復制,下次定時任務發起後從新鏈接。
4.4 權限驗證
若是主節點設置了requirepass參數,則須要密碼驗證,從節點必須配置masterauth參數保證與主節點相同的密碼才能經過驗證,若是驗證失敗,從節點會斷開復制,下次定時任務發起後從新鏈接。
4.5 數據同步
主從複製鏈接創建成功後,便開始數據同步,屬於數據的初始化,主節點會把持有的全部數據發送給從節點,主題是實現方式是從節點給主節點發送psync命令(2.8以前是sync命令)。這塊是耗時最長的步驟,分爲全量同步和部分同步。
4.6 命令持續同步
當主節點把當前的數據同步給從節點後,便完成了複製的創建流程,後續主節點會持續的把命令發送給從節點,保證主從一致。
主從創建鏈接成功後,從節點會向主節點發送psync命令來完成數據同步,同步過程分爲:全量複製和部分複製。
psync命令運行須要如下組件的支持:
master節點處理完寫入命令後,會把命令的字節長度作累加記錄。
從節點再接收到主節點發送的命令後,也會累加自身的偏移量。
經過對比master的偏移量和slave的偏移量來看slave和master的數據差別大小。
複製緩衝區是保存在主節點上的一個固定長度隊列,默認大小爲1MB,當有slave時候回建立緩衝區,這時主節點響應寫命令時,不但會把命令發送給從節點,還會寫入複製擠壓緩衝區。
擠壓緩衝區是一個先進先出的隊列,若是超過容量,以前的數據會被覆蓋。大小是能夠配置的。擠壓緩衝區主要爲了部分複製作準備。能夠經過info replication來查看:
repl_backlog_active:1 //開啓複製緩衝區 repl_backlog_size:1048576 //緩衝區最大長度 repl_backlog_first_byte_offset:4505 //起始變異量,計算當前緩衝區可用範圍 repl_backlog_histlen:5460 //已保存數據的有效長度
每一個redis節點(主從)啓動後都會生成一個40位的16進制的字符串做爲運行id,用於惟一識別一個redis節點。從節點會保存主節點的運行id用於識別本身正在複製的是哪個主節點。redis重啓後id會改變。
初次複製時,從節點會保存主節點的runid。
從節點經過給主節點發送psync命令實現部分複製或者全量複製。命令格式爲:
psync {runid} {offset}
第一次複製時沒有offset和主節點的runid,會發送psync -1命令
部分複製時redis針對全量複製開銷太高作出的一種優化措施,使用psync {runid}{offset}命令實現。
當主從複製的過程當中,若是出現網絡閃斷或者命令丟失等異常狀況,從節點會要求主節點補發數據,若是此時主節點的複製積壓緩衝區內存中恰好存在這部分數據(就是斷網這段時間沒有同步到從節點的數據),則直接發給從節點,最終保持了和從節點的一直,也避免了大規模的全量複製。
主節點判斷判斷知足部分複製的條件
若是不知足部分複製條件,則主節點會返回fullsync給從節點,從節點會開啓全量複製。
因而可知複製積壓緩衝區的大小比較重要,若是過小,會被覆蓋,最終致使主從網絡恢復後沒法進行部分複製,這個值得大小應該要基於網絡的中斷時間,已經主節點的qps和命令的大小來進行計算,而後進行合理的設置。
主從心跳檢測示意圖
master會週期性的ping slave,週期時間經過repl-ping-replica-period參數來控制,默認是10秒
slave每隔1秒迴向master發送replconf ack {offset}命令:
實時監測主從節點的網絡狀態
上報自身的數據複製偏移量,若是主節點發現從節點有數據缺失,主節點會從自身的複製積壓緩衝區中拉取數據發給從節點。
實現從節點的數量和延遲性功能,經過min-replicas-to-write(最小可用的從節點個數)和min-replicas-max-lag(容許的最小延遲秒,通常爲0,或者1)參數定義。
若是master開啓了這兩個參數,那麼若是可用的從節點小於min-replicas-to-write或者延遲大於min-replicas-max-lag,master會拒絕數據寫入。示意圖以下。
redis.conf有個repl-timeout參數:
slave角度,若是在repl-timeout時間內沒有收到傳輸的rdb snapshot數據,
slave角度,若是在repl-timeout沒有收到master發送的數據包或者ping。
master角度,若是在repl-timeout時間沒有收到REPCONF ACK確認信息。
當redis檢測到repl-timeout超時(默認值60s),將會關閉主從之間的鏈接,redis slave會從新創建主從鏈接的請求。這個值必定要大於repl-ping-replica-period參數
爲了下降主從延遲,通常建議把redis的主從節點部署在相同的機房。
全量複製很是重,應該儘可能避免,下面是一些會致使全量複製的操做。