Redis 之江湖遇險-複製運維及優化
一. 前言
上一篇Redis 之深入江湖-複製原理中說了複製的原理,那麼在理解複製原理之後,還要知道在這複製功能的背後,還有哪些坑要注意一下,畢竟坑是要跳過去的,而不是跳進去的。
二. 讀寫分離的一些問題
對於讀佔比較高的場景,可以通過把部分的讀流量分攤到slave節點來減輕master節點的壓力,同時需要注意master節點永遠只執行寫操作。如圖:
在使用slave節點響應讀請求時,業務端可能會遇到一些問題,如:複製資料延遲、讀到過期資料、slave節點故障。
1).資料延遲
Redis複製資料的延遲,是由於複製的一部特性導致的,因此無法避免。但是延遲主要是取決於網路頻寬和命令阻塞的情況而定,比如master節點剛寫入資料,在slave節點上是可能讀取不到資料的。在大量延遲的場景下,可以編寫外部程式監聽主從節點的複製偏移量,延遲較大時發出報警或通知,實現方式如下:
- 對於具體延遲,監控程式可通過檢查 info replication 的 offset 指標記錄,從節點的偏移量可以查詢主節點的offset指標,它們的差值就是主從延遲的位元組量。
- 如果位元組量過高,可以採用zookeeper的監聽回撥機制實現客戶端通知。
- 客戶端接收通知後,修改讀命令路由到主節點或其他從節點上,當延遲恢復後,再通知客戶端。
2).讀到過期資料
當master節點儲存大量超時的資料,譬如快取資料,Redis內部需要韻味過期資料的刪除策略。刪除策略主要有兩種:惰性刪除和定時刪除。
- 惰性刪除:master節點每次讀取命令時都會檢查鍵是否超時,如果超時則執行del命令刪除鍵物件,之後非同步把del命令slave節點,這樣可以保證資料複製的一致性,slave節點是永遠不會主動去刪除超時資料的。
- 定時刪除:Redis的master節點在內部定時任務,會迴圈取樣一定數量的鍵,當發現取樣的鍵過期時,會執行del命令,之後再同步個slave節點。
注:如果資料大量超時,master節點取樣速度跟不上過期的速度,而且master節點沒有讀取過期鍵的操作,那slave節點時無法收到del命令的,這時從節點上讀取的資料已經時超時的了。但是Redis3.2版本中已經解決了這個問題,在此版本中slave節點讀取資料之前會檢查鍵過期時間來決定是否返回資料的。
3).從節點故障問題
對於slave節點故障問題,是需要在客戶端維護可用的slave節點列表,當slave節點故障時,需立刻切換到其他從節點或主節點上。也可以通過 zookeeper 等協調者解決。
三.規避全量複製
全量複製時一個非常消耗資源的操作,因此避免全量複製是一個重要的關注點。全量複製通常有 3 種情況:第一次全量複製、節點執行 ID 不匹配、複製積壓緩衝區不足。
1). 第一次全量複製
由於時第一次建立複製,從節點沒有任何主節點的資料,因此必須進行全量複製才可以完成資料同步,對於這種情況的全量複製自然是無法避免的。當對資料量較大且流量較高的主節點從節點時,建議在低峰時操作,或者儘量規避使用大資料量的Redis節點。
2). 節點執行ID不匹配
當主從複製關係建立後,從節點會儲存主節點的執行ID,如果此時主節點出現故障重啟,那麼它的執行ID會改變。從節點發現執行ID不匹配後,會認為自己複製的是一個新的主節點,進而就回進行全量複製。對於這類情況,應該要從架構去規避,譬如提供故障轉移功能。當主節點發生故障後,手動提升從節點為主節點或者採用支援故障轉移的哨兵或叢集來解決。
3). 複製積壓緩衝區不足
在主從節點網路中斷時後,當從節點再次連上主節點時,會發送psync {offset} {runId} 命令請求部分複製,如果請求的偏移量不在主節點積壓緩衝區內,則無法提供給從節點資料,此時會使部分複製轉變為全量複製。針對此類情況,需根據網路中斷的時長,寫命令資料量分析出合理的積壓緩衝區的大小。寫命令的資料量會根據主節點每秒的info replication的master_repl_offset差值獲取(write_size_per_minute)。積壓緩衝區的預設大小為1MB,在大流量的場景顯然是不夠的,這時需要修改 repl_backlog_size 配置,從而避免因複製積壓緩衝區不足造成的全量複製。
四.規避複製風暴
複製風暴是指大量從節點對同一主節點或者同一臺機器的多個主節點,在短時間內發起全量複製的過程。此時將導致被髮起的主節點或機器產生大量開銷,如 :CPU、記憶體、硬碟、頻寬等。我們可以通過分析這樣的複製場景,然後採用合理的方式進行規避。規避方式如下:
1).單節點複製風暴
但節點複製風暴,一般是發生在主節點掛在多個從節點的場景下。當主節點重啟恢復後,從節點發起全量複製流程,此時主節點會為從節點建立RDB快照,如果在快照建立完畢之前,有多個從節點嘗試與主節點進行全量同步,那麼其他的從節點將共享這份RDB快照。這方面Redis做了相關優化,有效的避免了建立多個快照。但是同時像多個從節點發送快照,可能會使主節點的網路頻寬消耗嚴重,造成主節點延遲變大,極端情況會出現主從斷開,導致複製失敗。
解決方案:首先減少主節點掛在從節點的數量,或者採用樹樁複製結構。
2). 單機複製風暴
由於 Redis 的單執行緒架構,通常會在一臺物理機上部署多個Redis例項。如果這臺機器出現故障或網路長時間中斷,當他重啟恢復後,會有大量從節點針對這臺機器的主節點進行全量複製,會造成當前機器頻寬耗盡。
解決方案:(1). 應當把主節點儘量分散在多臺機器上,避免在單臺機器上部署過多的主節點。(2). 當主節點所在機器故障後提供故障恢復轉移機制,避免機器恢復後進行密集的全量複製。
五. 主從配置不一致
主從複製不一致是一個容易忽視的問題,對於有些配置可以不一樣,比如:主節點關閉 AOF而從節點開啟。但對於記憶體方面的配置必須要一致,例如: maxmemory
、hash-max-ziplist-entries
等引數,當配置的maxmemory
從節點的記憶體小於主節點,如果複製的資料量超過了從節點的 maxmemory,他會根據淘汰策略(maxmemory-policy)進行記憶體溢位控制,此時從節點資料已經丟失,但主從複製流程依然正常進行,複製偏移量也正常,但主從資料已經不一致。修復這類問題,也只能手動進行全量複製。
六. 迴歸
本文主要講了複製運維的一些問題及優化,例如讀寫分離的一些問題、規避全量複製、規避全量複製、主從配置不一致。
參考:《Redis開發與運維》
版權宣告:尊重博主原創文章,轉載請註明出處 https://www.cnblogs.com/hsdy