做者:程序員歷小冰
原文:https://mp.weixin.qq.com/s/0VVYTyAI1egfs2Fxcrme3A複製代碼
Redis 的複製功能分爲同步( sync )和命令傳播( command propagate )兩個步驟:程序員
同步面試
Redis 使用 psync 命令完成主從數據同步,同步過程分爲:全量複製和部分複製。數據庫
全量複製:通常用於初次複製場景,它會把主節點所有數據一次性發送給從節點發送給從節點,當數據量較大時,會對主從節點和網絡形成很大的開銷。緩存
部分複製:用於處理在主從複製中因網絡閃斷等緣由形成的網絡丟失場景,當從節點再次鏈接上主節點後,若是條件容許,主節點會補發丟失數據給從節點。由於補發的數據遠遠小於全量數據,能夠有效避免全量複製的太高開銷。bash
psync 命令運行須要如下組件支持:服務器
參與複製的從節點都會維護自身複製偏移量。主節點在處理完寫命令後,會把命令的字節長度作累加記錄,統計在 info replication 中的 masterreploffset 指標中。從節點在接收到主節點發送的命令後,也會累加記錄自身的偏移量,而且會每秒鐘上報自身的複製偏移量給主節點。經過對比主從節點的複製偏移量,能夠判斷主從節點數據是否一致。網絡
複製積壓緩衝區是保存在主節點的一個固定長度的隊列,默認大小爲 1MB,當主節點有鏈接的從節點時被建立。主節點響應寫命令時,不但會把命令發送給從節點,還會寫入複製積壓緩衝區中。架構
複製積壓緩衝區大小有限,只能保存最近的複製數據,用於部分複製和複製命令丟失時的數據補救。異步
每一個 Redis 節點啓動後都會動態分配一個 40 位的十六進制字符串做爲運行 ID。運行 ID 的主要做用是用來惟一標識 Redis 節點,好比說從節點保存主節點的運行 ID 來識別本身正在複製的是哪一個主節點。優化
全量同步
slaveof 命令的執行
須要注意,對於數據量較大的主節點,好比生成的 RDB 文件超過 6GB 以上時要格外當心。若是傳輸 RDB 的時間超過 repl-timeout 所配置的值,從節點將發起接收 RDB 文件並清理已經下載的臨時文件,致使全量複製失敗。
若是主節點建立和傳輸 RDB 的時間過長,可能會出現主節點複製客戶端緩衝區溢出。默認配置爲 client-output-buffer-limit slave 256MB 64MB 60,若是60s內緩衝區消耗持續大於64MB或者直接超過256MB時,主節點將直接關閉複製客戶端鏈接,形成全量同步失敗。
經過分析全量複製的全部流程,讀者會發現全量複製是一個很是耗時費力的操做。它時間開銷主要包括:
全量同步過程當中不只會消耗大量時間,還會進行屢次持久化相關操做和網絡數據傳輸,這期間會大量消耗主從節點所在服務器的 CPU、內存和網絡資源。因此,除了第一次複製是採用全量同步沒法避免,其餘場景應該規避全量複製,採起部分同步功能。
部分同步
部分複製主要是 Redis 針對全量複製的太高開銷作出的一種優化措施,使用 psync {runId} {offset} 命令實現。當從節點正在複製主節點時,若是出現網絡閃斷或者命令丟失等異常狀況時,從節點會向主節點要求補發丟失的命令數據,若是主節點的複製積壓緩衝區存在這部分數據則直接發送給從節點,這樣就保證了主從節點複製的一致性。補發的這部分數據通常遠遠小於全量數據,因此開銷很小。
心跳檢測
主從節點在創建複製後,它們之間維護着長鏈接並彼此發送心跳命令,以下圖所示。
主從心跳判斷機制以下所示:
replconf 命令不只能實時監測主從節點網絡狀態,還能上報從節點複製偏移量。主節點會根據從節點上傳的偏移量檢查複製數據是否丟失,若是從節點數據丟失,再從主節點的複製緩存區中拉取丟失的數據發送給該從節點。
異步複製和命令傳播
主節點不但負責數據讀寫,還負責把寫命令同步給從節點。寫命令的發送過程是異步完成,也就是說主節點自身處理完寫命令後直接返回給客戶端,並不等待從節點複製完成。
這個異步過程由命令傳播來處理,它不只會將寫命令發送給全部從服務器,還會將寫命令入隊到複製積壓緩衝區裏邊。