Redis 主從複製(八)

1. 主從複製簡介

1.1 單擊Redis的風險與問題

單機即在一臺機器上部署一個redis節點,主要會存在以下問題:

  • 機器故障
  • 現象:硬盤故障、系統崩潰
  • 本質:數據丟失,很可能對業務造成災難性打擊
  • 結論:基本上會放棄使用Redis
  • 容量瓶頸
  • 現象:內存不足,從16G升級到64G,從64G升級到128G,無限升級內存
  • 本質:窮或硬件條件跟不上
  • 結論:放棄使用Redis

爲了避免單點Redis服務器故障,準備多臺服務器,互相連通。將數據複製多個副本保存在不同的服 務器上,連接在一起,並保證數據是同步的。即使有其中一臺服務器宕機,其他服務器依然可以繼續提供服務,實現Redis的高可用,同時實現數據冗餘備份。

1.2 多臺服務器連接方案

在這裏插入圖片描述

  • 提供數據方:master,也可以叫做主服務器、主節點、主庫
  • 接收數據防:slave,從服務器、從節點、從庫
  • 需要解決的問題:數據同步
  • 核心工作:master的數據複製到slave中

1.3什麼是主從複製

主從複製,是指將一臺Redis服務器的數據,即時、有效的複製到其他的Redis服務器。前者稱爲主節點(master),後者稱爲從節點(slave);數據的複製是單向的,只能由主節點到從節點。

  • 特徵

一個master可以擁有多個slave,一個slave只對應一個master

  • 職責
  • master:
    寫數據
    執行寫操作時,將出現變化的數據自動同步到slave
    讀數據(可忽略)
  • slave:
    讀數據
    寫數據(禁止)

1.3 主從複製的作用

  • 讀寫分離:master寫、slave讀,提高服務器的讀寫負載能力
  • 負載均衡:基於主從結構,配合讀寫分離,由slave分擔master負載,並根據需求的變化,改變slave的數 量,通過多個從節點分擔數據讀取負載,大大提高Redis服務器併發量與數據吞吐量
  • 故障恢復:當master出現問題時,由slave提供服務,實現快速的故障恢復
  • 數據冗餘:實現數據熱備份,是持久化之外的一種數據備份方式
  • 高可用基石:基於主從複製,構建哨兵模式與集羣,實現Redis的高可用方案

2. 主從複製的使用

2.1 建立主從結構

需要注意,主從複製的開啓,完全是在從節點發起的,不需要我們在主節點做任何事情。
從節點開啓主從複製,有3種方式:

  • 客戶端發送命令
slaveof <masterip> <masterport>

注意是從服務器的客戶端發送命令

  • 啓動服務器參數
redis-server --slaveof <masterip> <masterport> 

注意是在從服務器的啓動命令(redis-server)後加--slaveof <masterip> <masterport>

  • 服務器配置
 slaveof <masterip> <masterport> 

注意是在從服務器的配置文件中加入此配置

工作中一般使用的是第三種方式,開啓了主從複製之後,可以在服務器(包括主從)開啓的頁面中看到相關信息,並且主服務器會自動將數據同步到從服務器中,不需要你做任何操作。

2.2 斷開主從

通過slaveof 命令建立主從複製關係以後,可以通過從服務器客戶端執行slaveof no one命令斷開。需要注意的是,從節點斷開復制後,不會刪除已有的數據,只是不再接受主節點新的數據變化。

3. 主從複製的工作流程

主從複製過程大致可以分爲3個階段

  • 建立連接階段
  • 數據同步階段
  • 命令傳播階段

在這裏插入圖片描述

3.1 建立連接階段

建立slave到master的連接,使master能夠識別slave,並保存slave端口號

  • 工作流程

slave 工作流程

  • 步驟1:設置master的地址和端口,保存master信息
  • 步驟2:建立socket連接
  • 步驟3:發送ping命令(定時器任務)
  • 步驟4:身份驗證
  • 步驟5:發送slave端口信息
    如圖,左邊是master做的事情,右邊是slave做的事情
    在這裏插入圖片描述

最終達到的狀態

  • slave:保存master的地址與端口號
  • master:保存slave的端口號
  • 總體:之間創建了socket連接

3.2 數據同步階段

  • 在slave初次連接後,複製master中的所有數據到slave,全量複製

  • 將slave的數據庫狀態更新成master當前的數據庫狀態(全量複製過程中,新的數據變化),部分複製

  • 工作流程

slave 工作流程

  • 步驟1:請求同步數據
  • 步驟2:創建RDB同步數據
  • 步驟3:恢復RDB同步數據
  • 步驟4:請求部分同步數據
  • 步驟5:恢復部分同步數據
    至此,數據同步工作完成
    在這裏插入圖片描述

最終達到的狀態

  • salve:具有master端全部數據,包含RDB過程接收的數據
  • master:保存slave當前數據同步的位置
  • 總體:之間完成了數據克隆

注意

  • 在數據同步階段之前,從節點是主節點的客戶端,主節點不是從節點的客戶端;而到了這一階段及以後,主從節點互爲客戶端。原因在於:在此之前,主節點只需要響應從節點的請求即可,不需要主動發請求,而在數據同步階段和後面的命令傳播階段,主節點需要主動向從節點發送請求(如推送緩衝區中的寫命令),才能完成複製。
  • 如果網絡中斷時間過長,導致主節點沒有能夠完整地保存中斷期間執行的寫命令(緩衝區中的指令被擠出去了),則無法進行部分複製,仍使用全量複製。
  • 複製緩衝區大小設定不合理,會導致數據溢出。如進行全量複製週期太長,進行部分複製時發現數據已 經存在丟失的情況,必須進行第二次全量複製,致使slave陷入死循環狀態。 可以使用 repl-backlog-size 屬性配置緩衝區大小
  • 主節點通過網絡將RDB文件發送給從節點,對主從節點的帶寬都會帶來很大的消耗
  • 主節點通過bgsave命令fork子進程進行RDB持久化,該過程是非常消耗CPU、內存(頁表複製)、硬盤IO的
  • 從節點首先清除自己的舊數據,然後執行RDB文件恢復數據

3.3 命令傳播階段

數據同步階段完成後,主從節點進入命令傳播階段;在這個階段,主節點將自己執行的寫命令發送給從節點,從節點接收命令並執行,從而實時的保證主從節點數據的一致性(通過心跳機制實現)。
需要注意的是,命令傳播是異步的過程,即主節點發送寫命令後並不會等待從節點的回覆;因此實際上主從節點之間很難保持實時的一致性,延遲在所難免。數據不一致的程度,與主從節點之間的網絡狀況、主節點寫命令的執行頻率、以及主節點中的repl-disable-tcp-nodelay配置等有關。

  • 命令傳播階段出現斷網現象
  • 網絡閃斷閃連 ——忽略
  • 短時間網絡中斷 ——部分複製
  • 長時間網絡中斷 ——全量複製

3.4 部分複製的核心要素

部分複製除了用於同步階段外,還用於網絡中斷等情況後的複製,只將中斷期間主節點執行的寫命令發送給從節點,與全量複製相比更加高效。需要注意的是,如果網絡中斷時間過長,導致主節點沒有能夠完整地保存中斷期間執行的寫命令,則無法進行部分複製,仍使用全量複製。部分複製的實現,依賴於下面三個重要的概念:

  • 服務器運行ID(runid)
  • 概念:服務器運行ID是每一臺服務器每次運行的身份識別碼,一臺服務器多次運行可以生成多個運行id
  • 組成:運行id由40位字符組成,是一個隨機的十六進制字符 例如fdc9ff13b9bbaab28db42b3d50f852bb5e3fcdce
  • 作用:運行id被用於在服務器間進行傳輸,識別身份 ,如果想兩次操作均對同一臺服務器進行,必須每次操作攜帶對應的運行id,用於對方識別
  • 實現方式:運行id在每臺服務器啓動時自動生成的,master在首次連接slave時,會將自己的運行ID發 送給slave,slave保存此ID,通過info Server命令,可以查看節點的runid
  • 複製緩衝區
    在命令傳播階段,主節點除了將寫命令發送給從節點,還會發送一份給複製積壓緩衝區,作爲寫命令的備份
  • 概念:複製緩衝區,又名複製積壓緩衝區,是一個先進先出(FIFO)的隊列,用於存儲服務器執行過的命令,每次傳播命令,master都會將傳播的命令記錄下來,並存儲在複製緩衝區 。 複製緩衝區默認數據存儲空間大小是1M,由於存儲空間大小是固定的,當入隊元素的數量大於隊 列長度時,最先入隊的元素會被彈出,而新元素會被放入隊列
  • 由來:每臺服務器啓動時,如果開啓有AOF或被連接成爲master節點,即創建複製緩衝區
  • 作用:用於保存master收到的所有指令(僅影響數據變更的指令,例如set,select)
  • 數據來源:當master接收到主客戶端的指令時,除了將指令執行,會將該指令存儲到緩衝區中
  • 複製緩衝區工作原理

組成

  • 偏移量
  • 字節值

工作原理

  • 通過offset區分不同的slave當前數據傳播的差異
  • master記錄已發送的信息對應的offset
  • slave記錄已接收的信息對應的offset
  • 主節點根據offset和緩衝區大小決定能否執行部分複製,如果offset偏移量之後的數據,仍然都在複製積壓緩衝區裏,則執行部分複製;如果offset偏移量之後的數據已不在複製積壓緩衝區中(數據已被擠出),則執行全量複製。也就是判斷指令是否被擠出去,如果被擠出,就全量複製,沒有被擠出去,就部分複製
    在這裏插入圖片描述
  • 偏移量
  • 概念:一個數字,描述複製緩衝區中的指令字節位置
  • 分類:
    master複製偏移量:記錄發送給所有slave的指令字節對應的位置(多個)
    slave複製偏移量:記錄slave接收master發送過來的指令字節對應的位置(一個)
  • 數據來源
    master端:發送一次記錄一次
    slave端:接收一次記錄一次
  • 作用
    同步信息,比對master與slave的差異,當slave斷線後,恢復數據使用

3.4 數據同步和命令傳播階段詳細工作流程

在這裏插入圖片描述

3.5 心跳機制

  • 在命令傳播階段,master與slave間需要進行信息交換,使用心跳機制進行維護,實現雙方連接保持在線

master 心跳
指令:ping
週期:由repl-ping-slave-period 決定,默認10秒
作用:判斷slave 是否在線
查詢:info replication 獲取slave最後一次連接時間間隔,lag 項維持在0或1視爲正常

slave 心跳

  • 指令:replconf ack offset
  • 週期:1秒
  • 作用:彙報slave自己的複製偏移量,獲取最新的數據變更指令。判斷master是否在線
  • 心跳階段注意事項
  • 當slave多數掉線,或延遲過高時,master爲保障數據穩定性,將拒絕所有信息同步操作,使用下面兩個參數進行配置
    min-slaves-to-write 2 主從複製的最小slave數
    min-slaves-max-lag 8 主從複製所有slave的最大延遲
    slave數量少於2個,或者所有slave的延遲都大於等於8秒時,強制關閉master寫功能,停止數據同步
    slave數量和延遲由slave發送REPLCONF ACK命令做確認

3.6 完整流程

在這裏插入圖片描述

4. 主從複製常見問題

  • 頻繁的全量複製

伴隨着系統的運行,master的數據量會越來越大,一旦master重啓,runid將發生變化,會導致全部slave的 全量複製操作

  • 內部優化調整方案
  1. master內部創建master_replid變量,使用runid相同的策略生成,長度41位,併發送給所有slave
  2. 在master關閉時執行命令 shutdown save,進行RDB持久化,將runid與offset保存到RDB文件中 ,通過redis-check-rdb命令可以查看該信息
  3. master重啓後,將RDB文件中保存的repl-id與repl-offset加載到內存中 ,通過info命令可以查看該信息
  • 作用
    本機上次runid,重啓後恢復該值,使所有slave認爲還是之前的master
  • 頻繁的全量複製2
  • 問題現象:網絡環境不佳,出現網絡中斷,slave不提供服務
  • 問題原因:複製緩衝區過小,斷網後slave的offset越界,觸發全量複製
  • 最終結果:slave反覆進行全量複製
  • 解決方案
    修改複製緩衝區大小,repl-backlog-size
  • 建議設置如下:
  1. 測算從master到slave的重連平均時長second
  2. 獲取master平均每秒產生寫命令數據總量write_size_per_second
  3. 最優複製緩衝區空間 = 2 * second * write_size_per_second
  • 頻繁的網絡中斷
  • 問題現象: master的CPU佔用過高 或 slave頻繁斷開連接
  • 問題原因
    slave每1秒發送REPLCONF ACK命令到master
    當slave接到了慢查詢時(keys * ,hgetall等),會大量佔用CPU性能
    master每1秒調用複製定時函數replicationCron(),比對slave發現長時間沒有進行響應
  • 最終結果
    master各種資源(輸出緩衝區、帶寬、連接等)被嚴重佔用
  • 解決方案
    通過設置合理的超時時間(repl-timeout,該參數定義了超時時間的閾值(默認60秒),超過該值,釋放slave ),確認是否釋放slave
  • 頻繁的網絡中斷2
  • 問題現象:slave與master連接斷開
  • 問題原因
    master發送ping指令頻度較低
    master設定超時時間較短
    ping指令在網絡中存在丟包
  • 解決方案
    提高ping指令發送的頻度 repl-ping-slave-period,超時時間repl-time的時間至少是ping指令頻度的5到10倍,否則slave很容易判定超時
  • 數據不一致
  • 問題現象:多個slave獲取相同數據不同步
  • 問題原因: 網絡信息不同步,數據發送有延遲
  • 解決方案
    優化主從間的網絡環境,通常放置在同一個機房部署,如使用阿里雲等雲服務器時要注意此現象
    監控主從節點延遲(通過offset)判斷,如果slave延遲過大,暫時屏蔽程序對該slave的數據訪問
    slave-serve-stale-data yes|no 開啓後僅響應info、slaveof等少數命令(慎用,除非對數據一致性要求很高)

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章