1. 程式人生 > >Redis 之江湖遇險-復制運維及優化

Redis 之江湖遇險-復制運維及優化

html 所在 協調 定時 主從復制 請求 查詢 前言 gin

一. 前言

  上一篇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而從節點開啟。但對於內存方面的配置必須要一致,例如: maxmemoryhash-max-ziplist-entries 等參數,當配置的maxmemory從節點的內存小於主節點,如果復制的數據量超過了從節點的 maxmemory,他會根據淘汰策略(maxmemory-policy)進行內存溢出控制,此時從節點數據已經丟失,但主從復制流程依然正常進行,復制偏移量也正常,但主從數據已經不一致。修復這類問題,也只能手動進行全量復制。


六. 回歸

  本文主要講了復制運維的一些問題及優化,例如讀寫分離的一些問題、規避全量復制、規避全量復制、主從配置不一致。

參考:《Redis開發與運維》

版權聲明:尊重博主原創文章,轉載請註明出處 https://www.cnblogs.com/hsdy

Redis 之江湖遇險-復制運維及優化