全部產品
Search
文件中心

:排查記憶體使用量率高的問題

更新時間:Jun 30, 2024

雲原生記憶體資料庫Tair可提供高效的資料庫服務,當記憶體不足時,可能導致Key頻繁被逐出、回應時間上升、QPS(每秒訪問次數)不穩定等問題,進而影響業務運行。通常情況下,當記憶體使用量率超過95%時需要及時關注。

Tair記憶體佔用介紹

Redis的記憶體佔用主要由以下三部分組成:

記憶體佔用說明
鏈路記憶體(動態)主要包括Input Buff、Output Buff、JIT Overhead、Fake Lua Link、Lua執行緩衝等,例如可執行INFO命令,通過返回結果的Clients中查看用戶端緩衝資訊。
說明 Input buff與Output buff與每個用戶端的串連有關,通常較小。當執行用戶端Range類操作或大Key收發較慢時,Input buff與Output buff佔用的記憶體會增大,從而影響資料區,甚至會造成記憶體溢出OOM(Out Of Memory)。
資料記憶體使用者資料區,即實際儲存的Value資訊,通常作為重點分析的對象。
管理記憶體(靜態)啟動時較小且相對恒定,該地區由管理資料的Hash記憶體開銷、Repl-buff與aof-buff的記憶體開銷(約32 MB~64 MB)等構成。
說明 當Key數量特別多時(例如幾億個),會佔用較大的記憶體。
說明 大部分OOM情境是由於動態記憶體管理失效引起,例如限流時請求堆積導致動態記憶體快速上升、過於複雜或不合理的Lua指令碼也可能導致OOM。

步驟一:分析記憶體使用量情況

  1. 查詢指定時段的記憶體使用量率資訊,具體操作,請參見查看效能監控

    以下樣本中,記憶體使用量率(即Memory Usage監控指標)持續接近100%,如下圖所示:

    圖 1. 記憶體使用量率樣本記憶體使用量率樣本
    說明 對於叢集架構讀寫分離架構的執行個體,當選擇展示資料節點彙總指標時,Memory Usage展示的是該執行個體下所有資料節點記憶體使用量率的平均值(不含唯讀節點)。
  2. 查詢歷史累計逐出的Key總數和命令的最大時延,分析是否呈現明顯的上升趨勢。

    以下樣本中,在同一時間點(2021年1月7日16點整),歷史累計逐出的Key總數和命令的最大時延均呈現顯著上升趨勢,表明存在記憶體不足的問題。

    說明 需關注的監控指標為Evicted Keys(歷史累計逐出的Key總數)和Max Rt(資料節點從接收命令到發出響應最大時延)。
    圖 2. 效能監控樣本效能監控樣本
  3. 可選:Tair的記憶體使用量率不符合預期時,可執行下述步驟詳細分析記憶體使用量情況。
    1. 通過redis-cli串連Tair
    2. Tair命令列中,執行MEMORY STATS命令查詢記憶體使用量詳情。
      Tair執行個體的記憶體開銷主要由兩部分組成:
      • 業務資料的記憶體開銷,該部分一般作為重點分析對象。
      • 非業務資料的記憶體開銷,例如主備複製的積壓緩衝區、Tair進程初始化消耗的記憶體等。

      返回樣本及各參數對應的解釋如下:

      說明 下述返回資訊中,記憶體數值的單位為位元組。
       1) "peak.allocated" //Tair進程自啟動以來消耗記憶體的峰值。
       2) (integer) 79492312
       3) "total.allocated" //Tair使用其分配器分配的總位元組數,即當前的總記憶體使用量量。
       4) (integer) 79307776
       5) "startup.allocated" //Tair啟動時消耗的初始記憶體量。
       6) (integer) 45582592
       7) "replication.backlog" //複製積壓緩衝區的大小。
       8) (integer) 33554432
       9) "clients.slaves" //主從複製中所有從節點的讀寫緩衝區大小。
      10) (integer) 17266
      11) "clients.normal" //除從節點外,所有其他用戶端的讀寫緩衝區大小。
      12) (integer) 119102
      13) "aof.buffer" //AOF持久化使用的緩衝和AOF重寫時產生的緩衝。
      14) (integer) 0
      15) "db.0"  //業務資料庫的數量。
      16) 1) "overhead.hashtable.main" //當前資料庫的hash鏈表開銷記憶體總和,即中繼資料記憶體。
          2) (integer) 144
          3) "overhead.hashtable.expires" //用於儲存key的到期時間所消耗的記憶體。
          4) (integer) 0
      17) "overhead.total" //數值=startup.allocated+replication.backlog+clients.slaves+clients.normal+aof.buffer+db.X。
      18) (integer) 79273616
      19) "keys.count" //當前Tair執行個體的key總數
      20) (integer) 2
      21) "keys.bytes-per-key" //當前Tair執行個體每個key的平均大小,計算公式:(total.allocated-startup.allocated)/keys.count。
      22) (integer) 16862592
      23) "dataset.bytes" //純業務資料佔用的記憶體大小。
      24) (integer) 34160
      25) "dataset.percentage" //純業務資料佔用的記憶體比例,計算公式:dataset.bytes*100/(total.allocated-startup.allocated)。
      26) "0.1012892946600914"
      27) "peak.percentage" //當前總記憶體與歷史峰值的比例,計算公式:total.allocated*100/peak.allocated。
      28) "99.767860412597656"
      29) "fragmentation" //記憶體的片段率。
      30) "0.45836541056632996"
    3. Tair命令列中,執行MEMORY USAGE命令查詢指定Key消耗的記憶體(單位為位元組)。

      命令執行樣本:

      MEMORY USAGE Key0089393003

      返回資訊如下:

      (integer) 1000072
    4. Tair命令列中,執行MEMORY DOCTOR命令擷取記憶體診斷建議。
      圖 3. 診斷結果樣本診斷結果樣本
      MEMORY DOCTOR會從以下維度為Tair執行個體的提供記憶體診斷建議,您可以根據診斷建議制定相應的最佳化策略:
          int empty = 0;     /* Instance is empty or almost empty. */
          int big_peak = 0;       /* Memory peak is much larger than used mem. */
          int high_frag = 0;      /* High fragmentation. */
          int high_alloc_frag = 0;/* High allocator fragmentation. */
          int high_proc_rss = 0;  /* High process rss overhead. */
          int high_alloc_rss = 0; /* High rss overhead. */
          int big_slave_buf = 0;  /* Slave buffers are too big. */
          int big_client_buf = 0; /* Client buffers are too big. */
          int many_scripts = 0;   /* Script cache has too many scripts. */

步驟二:最佳化記憶體使用量率

  1. 查詢現有的Key是否符合業務預期,及時清理無用的Key。
  2. 通過緩衝分析功能,分析大Key分布和Key的TTL到期策略。具體操作,請參見離線全量Key分析
    1. 分析Key是否有合理的TTL策略。
      說明 以下樣本中,所有的Key均未設定到期時間,建議根據業務需求來衡量,並在應用端設定合理的到期時間。
      圖 4. Key的到期時間分布樣本Key的到期時間分布樣本
    2. 對大Key進行評估,然後從業務方向對大Key進行拆分。
      圖 5. 大Key分析樣本大Key分析樣本
  3. 根據業務需求,設定合理的資料逐出策略(即調整maxmemory-policy參數的值)。具體操作,請參見設定執行個體參數
    說明 Tair預設的資料逐出策略為volatile-lru,更多資訊,請參見Tair配置參數列表
  4. 根據業務需求,設定合理的到期Key主動刪除的執行頻率(即調整hz參數的值)。具體操作,請參見調整Tair定期任務的執行頻率
    說明 hz的取值建議在100以內,如果該值過大將對CPU的使用率產生較大影響。您也可以設定為自動調整(要求執行個體為記憶體型或持久記憶體型),具體操作,請參見自動調整Tair定期任務的執行頻率
  5. 經過上述步驟最佳化後,流量使用率依舊較高,可評估升級至更大記憶體的規格,以承載更大的網路流量。具體操作,請參見變更執行個體配置
    說明 在正式升級執行個體的規格前,您可以先購買一個隨用隨付的執行個體,測試要升級到的目標規格是否能夠滿足業務的負載需求,測試完成後可將其釋放。關於如何釋放執行個體,請參見釋放隨用隨付執行個體