Redis - 8 主從複製
Redis - 主從複製
2.1 主從複製簡介
2.1.1 高可用
首先我們要理解網際網路應用因為其獨有的特性我們演化出的三高架構
-
高併發
應用要提供某一業務要能支援很多客戶端同時訪問的能力,我們稱為併發,高併發意思就很明確了
-
高效能
效能帶給我們最直觀的感受就是:速度快,時間短
-
高可用
可用性:一年中應用服務正常執行的時間佔全年時間的百分比,如下圖:表示了應用服務在全年宕機的時間
我們把這些時間加在一起就是全年應用服務不可用的時間,然後我們可以得到應用服務全年可用的時間
4小時27分15秒+11分36秒+2分16秒=4小時41分7秒=16867秒
1年=36524
60*60=31536000秒可用性=(31536000-16867)/31536000*100%=99.9465151%
業界可用性目標5個9,即99.999%,即伺服器年宕機時長低於315秒,約5.25分鐘
2.1.2 主從複製概念
知道了三高的概念之後,我們想:你的“Redis”是否高可用?那我們要來分析單機redis的風險與問題
問題1.機器故障
- 現象:硬碟故障、系統崩潰
- 本質:資料丟失,很可能對業務造成災難性打擊
- 結論:基本上會放棄使用redis.
問題2.容量瓶頸
- 現象:記憶體不足,從16G升級到64G,從64G升級到128G,無限升級記憶體
- 本質:窮,硬體條件跟不上
- 結論:放棄使用redis
結論:
為了避免單點Redis伺服器故障,準備多臺伺服器,互相連通。將資料複製多個副本儲存在不同的伺服器上,連線在一起,並保證資料是同步的。即使有其中一臺伺服器宕機,其他伺服器依然可以繼續提供服務,實現Redis的高可用,同時實現資料冗餘備份。
多臺伺服器連線方案:
- 提供資料方:master
主伺服器,主節點,主庫主客戶端
- 接收資料方:slave
從伺服器,從節點,從庫
從客戶端
- 需要解決的問題:
資料同步(master的資料複製到slave中)
這裡我們可以來解釋主從複製的概念:
概念:主從複製即將master中的資料即時、有效的複製到slave中
特徵:一個master可以擁有多個slave,一個slave只對應一個master
職責:master和slave各自的職責不一樣
master:
寫資料
執行寫操作時,將出現變化的資料自動同步到slave
讀資料(可忽略)
slave:
讀資料
寫資料(禁止)
2.1.3 主從複製的作用
- 讀寫分離:master寫、slave讀,提高伺服器的讀寫負載能力
- 負載均衡:基於主從結構,配合讀寫分離,由slave分擔master負載,並根據需求的變化,改變slave的數 量,通過多個從節點分擔資料讀取負載,大大提高Redis伺服器併發量與資料吞吐量
- 故障恢復:當master出現問題時,由slave提供服務,實現快速的故障恢復
- 資料冗餘:實現資料熱備份,是持久化之外的一種資料冗餘方式
- 高可用基石:基於主從複製,構建哨兵模式與叢集,實現Redis的高可用方案
2.2 主從複製工作流程
主從複製過程大體可以分為3個階段
- 建立連線階段(即準備階段)
- 資料同步階段
- 命令傳播階段(反覆同步)
而命令的傳播其實有4種,分別如下:
2.2.1 主從複製的工作流程(三個階段)
2.2.1.1 階段一:建立連線
建立slave到master的連線,使master能夠識別slave,並儲存slave埠號
流程如下:
- 步驟1:設定master的地址和埠,儲存master資訊
- 步驟2:建立socket連線
- 步驟3:傳送ping命令(定時器任務)
- 步驟4:身份驗證
- 步驟5:傳送slave埠資訊
至此,主從連線成功!
當前狀態:
slave:儲存master的地址與埠
master:儲存slave的埠
總體:之間建立了連線的socket
master和slave互聯
接下來就要通過某種方式將master和slave連線到一起
方式一:客戶端傳送命令
slaveof masterip masterport
方式二:啟動伺服器引數
redis-server --slaveof masterip masterport
方式三:伺服器配置(主流方式)
slaveof masterip masterport
slave系統資訊
master_link_down_since_seconds
masterhost & masterport
master系統資訊
uslave_listening_port(多個)
主從斷開連線
斷開slave與master的連線,slave斷開連線後,不會刪除已有資料,只是不再接受master傳送的資料
slaveof no one
授權訪問
master客戶端傳送命令設定密碼
requirepass password
master配置檔案設定密碼
config set requirepass password
config get requirepass
slave客戶端傳送命令設定密碼
auth password
slave配置檔案設定密碼
masterauth password
slave啟動伺服器設定密碼
redis-server –a password
2.2.1.2 階段二:資料同步
- 在slave初次連線master後,複製master中的所有資料到slave
- 將slave的資料庫狀態更新成master當前的資料庫狀態
同步過程如下:
- 步驟1:請求同步資料
- 步驟2:建立RDB同步資料
- 步驟3:恢復RDB同步資料
- 步驟4:請求部分同步資料
- 步驟5:恢復部分同步資料
至此,資料同步工作完成!
當前狀態:
slave:具有master端全部資料,包含RDB過程接收的資料
master:儲存slave當前資料同步的位置
總體:之間完成了資料克隆
資料同步階段master說明
1:如果master資料量巨大,資料同步階段應避開流量高峰期,避免造成master阻塞,影響業務正常執行
2:複製緩衝區大小設定不合理,會導致資料溢位。如進行全量複製週期太長,進行部分複製時發現數據已經存在丟失的情況,必須進行第二次全量複製,致使slave陷入死迴圈狀態。
repl-backlog-size ?mb
- master單機記憶體佔用主機記憶體的比例不應過大,建議使用50%-70%的記憶體,留下30%-50%的記憶體用於執 行bgsave命令和建立複製緩衝區
資料同步階段slave說明
- 為避免slave進行全量複製、部分複製時伺服器響應阻塞或資料不同步,建議關閉此期間的對外服務
slave-serve-stale-data yes|no
-
資料同步階段,master傳送給slave資訊可以理解master是slave的一個客戶端,主動向slave傳送命令
-
多個slave同時對master請求資料同步,master傳送的RDB檔案增多,會對頻寬造成巨大沖擊,如果master頻寬不足,因此資料同步需要根據業務需求,適量錯峰
-
slave過多時,建議調整拓撲結構,由一主多從結構變為樹狀結構,中間的節點既是master,也是 slave。注意使用樹狀結構時,由於層級深度,導致深度越高的slave與最頂層master間資料同步延遲 較大,資料一致性變差,應謹慎選擇
2.2.1.3 階段三:命令傳播
- 當master資料庫狀態被修改後,導致主從伺服器資料庫狀態不一致,此時需要讓主從資料同步到一致的狀態,同步的動作稱為命令傳播
- master將接收到的資料變更命令傳送給slave,slave接收命令後執行命令
命令傳播階段的部分複製
命令傳播階段出現了斷網現象:
網路閃斷閃連:忽略
短時間網路中斷:部分複製
長時間網路中斷:全量複製
這裡我們主要來看部分複製,部分複製的三個核心要素
- 伺服器的執行 id(run id)
- 主伺服器的複製積壓緩衝區
- 主從伺服器的複製偏移量
- 伺服器執行ID(runid)
概念:伺服器執行ID是每一臺伺服器每次執行的身份識別碼,一臺伺服器多次執行可以生成多個執行id
組成:執行id由40位字元組成,是一個隨機的十六進位制字元
例如:fdc9ff13b9bbaab28db42b3d50f852bb5e3fcdce
作用:執行id被用於在伺服器間進行傳輸,識別身份
如果想兩次操作均對同一臺伺服器進行,必須每次操作攜帶對應的執行id,用於對方識別
實現方式:執行id在每臺伺服器啟動時自動生成的,master在首次連線slave時,會將自己的執行ID傳送給slave,
slave儲存此ID,通過info Server命令,可以檢視節點的runid
- 複製緩衝區
概念:複製緩衝區,又名複製積壓緩衝區,是一個先進先出(FIFO)的佇列,用於儲存伺服器執行過的命令,每次傳播命令,master都會將傳播的命令記錄下來,並存儲在複製緩衝區
複製緩衝區預設資料儲存空間大小是1M
當入隊元素的數量大於佇列長度時,最先入隊的元素會被彈出,而新元素會被放入佇列
作用:用於儲存master收到的所有指令(僅影響資料變更的指令,例如set,select)
資料來源:當master接收到主客戶端的指令時,除了將指令執行,會將該指令儲存到緩衝區中
複製緩衝區內部工作原理:
組成
-
偏移量
概念:一個數字,描述複製緩衝區中的指令位元組位置
分類:
- master複製偏移量:記錄傳送給所有slave的指令位元組對應的位置(多個)
- slave複製偏移量:記錄slave接收master傳送過來的指令位元組對應的位置(一個)
作用:同步資訊,比對master與slave的差異,當slave斷線後,恢復資料使用
資料來源:
- master端:傳送一次記錄一次
- slave端:接收一次記錄一次
-
位元組值
工作原理
- 通過offset區分不同的slave當前資料傳播的差異
- master記錄已傳送的資訊對應的offset
- slave記錄已接收的資訊對應的offset
2.2.2 流程更新(全量複製/部分複製)
我們再次的總結一下主從複製的三個階段的工作流程:
2.2.3 心跳機制
什麼是心跳機制?
進入命令傳播階段候,master與slave間需要進行資訊交換,使用心跳機制進行維護,實現雙方連線保持線上
master心跳:
- 內部指令:PING
- 週期:由repl-ping-slave-period決定,預設10秒
- 作用:判斷slave是否線上
- 查詢:INFO replication 獲取slave最後一次連線時間間隔,lag項維持在0或1視為正常
slave心跳任務
- 內部指令:REPLCONF ACK {offset}
- 週期:1秒
- 作用1:彙報slave自己的複製偏移量,獲取最新的資料變更指令
- 作用2:判斷master是否線上
心跳階段注意事項:
- 當slave多數掉線,或延遲過高時,master為保障資料穩定性,將拒絕所有資訊同步
min-slaves-to-write 2
min-slaves-max-lag 8
slave數量少於2個,或者所有slave的延遲都大於等於8秒時,強制關閉master寫功能,停止資料同步
-
slave數量由slave傳送REPLCONF ACK命令做確認
-
slave延遲由slave傳送REPLCONF ACK命令做確認
至此:我們可以總結出完整的主從複製流程:
2.3 主從複製常見問題
2.3.1 頻繁的全量複製
- 伴隨著系統的執行,master的資料量會越來越大,一旦master重啟,runid將發生變化,會導致全部slave的全量複製操作
內部優化調整方案:
1:master內部建立master_replid變數,使用runid相同的策略生成,長度41位,併發送給所有slave
2:在master關閉時執行命令shutdown save,進行RDB持久化,將runid與offset儲存到RDB檔案中
repl-id repl-offset
通過redis-check-rdb命令可以檢視該資訊
3:master重啟後加載RDB檔案,恢復資料,重啟後,將RDB檔案中儲存的repl-id與repl-offset載入到記憶體中
master_repl_id=repl master_repl_offset =repl-offset
通過info命令可以檢視該資訊
作用:本機儲存上次runid,重啟後恢復該值,使所有slave認為還是之前的master
- 第二種出現頻繁全量複製的問題現象:網路環境不佳,出現網路中斷,slave不提供服務
問題原因:複製緩衝區過小,斷網後slave的offset越界,觸發全量複製
最終結果:slave反覆進行全量複製
解決方案:修改複製緩衝區大小
repl-backlog-size ?mb
建議設定如下:
1.測算從master到slave的重連平均時長second
2.獲取master平均每秒產生寫命令資料總量write_size_per_second
3.最優複製緩衝區空間 = 2 * second * write_size_per_second
2.3.2 頻繁的網路中斷
- 問題現象:master的CPU佔用過高 或 slave頻繁斷開連線
問題原因
slave每1秒傳送REPLCONFACK命令到master
當slave接到了慢查詢時(keys * ,hgetall等),會大量佔用CPU效能
master每1秒呼叫複製定時函式replicationCron(),比對slave發現長時間沒有進行響應
最終結果:master各種資源(輸出緩衝區、頻寬、連線等)被嚴重佔用
解決方案:通過設定合理的超時時間,確認是否釋放slave
repl-timeout seconds
該引數定義了超時時間的閾值(預設60秒),超過該值,釋放slave
- 問題現象:slave與master連線斷開
問題原因
master傳送ping指令頻度較低
master設定超時時間較短
ping指令在網路中存在丟包
解決方案:提高ping指令傳送的頻度
repl-ping-slave-period seconds
超時時間repl-time的時間至少是ping指令頻度的5到10倍,否則slave很容易判定超時
2.3.3 資料不一致
問題現象:多個slave獲取相同資料不同步
問題原因:網路資訊不同步,資料傳送有延遲
解決方案
優化主從間的網路環境,通常放置在同一個機房部署,如使用阿里雲等雲伺服器時要注意此現象
監控主從節點延遲(通過offset)判斷,如果slave延遲過大,暫時遮蔽程式對該slave的資料訪問
slave-serve-stale-data yes|no
開啟後僅響應info、slaveof等少數命令(慎用,除非對資料一致性要求很高)