記憶體管理最佳做法

如果未正確管理及設定 Memorystore for Redis 執行個體,可能會導致記憶體壓力,進而影響應用程式效能。本頁面說明有效管理執行個體記憶體用量的最佳做法。

本主題內容:

記憶體管理概念

本節將介紹管理執行個體記憶體用量時需要瞭解的概念。

執行個體容量

  • 執行個體容量是指您佈建的記憶體量 (以 GB 為單位),也是您需要支付的費用。如要進一步瞭解如何選取適當的執行個體容量,請參閱「調整 Memorystore 執行個體大小」。

maxmemory 設定

  • Maxmemory 是 Redis 設定,可讓您設定記憶體限制,達到限制時,系統就會套用移除政策。Memorystore for Redis 會將這項設定指定為 maxmemory-gb。建立執行個體時,maxmemory-gb 會設為執行個體容量。視系統記憶體用量比率指標而定,您可能需要降低 maxmemory-gb 限制,為工作負載尖峰提供記憶體負擔。

    詳情請參閱「管理系統記憶體用量比率」。

    如要瞭解如何調整 maxmemory-gb,請參閱「設定 Redis 執行個體」。

系統記憶體用量比率

  • 「系統記憶體用量比率」指標可讓您測量執行個體相對於系統記憶體的記憶體用量。系統記憶體由 Memorystore 自動管理,可處理因記憶體密集型作業和記憶體片段化 (開放原始碼 Redis 中常見的情況) 造成的記憶體用量尖峰。

    如果系統記憶體用量比率指標超過 80%,表示執行個體記憶體不足,請按照「管理系統記憶體用量比率」一文中的說明操作。如果不採取行動,記憶體用量持續增加,執行個體可能會因記憶體不足而當機。由於記憶體片段化,系統記憶體用量比率指標可能會超過 80%。或者,如果指標快速飆升至 80% 以上,您可能使用了其中一項記憶體密集型作業

    維護更新期間,系統記憶體使用率應為 50% 以下。此外,有時匯出需要系統記憶體使用率低於 50%。

已使用的記憶體

  • 「已用記憶體」指標會顯示 Memorystore 執行個體中的資料量。執行個體的記憶體用量最多可達到 maxmemory-gb 設定上限。當使用的記憶體超過 maxmemory-gb 限制時,系統會套用移除政策。

驅逐政策

  • 執行個體的撤銷政策 (也稱為 Maxmemory 政策) 會決定執行個體資料達到 maxmemory-gb 限制時,Redis 撤銷金鑰的方式。Redis 會在一般快取使用情境中逐出鍵。金鑰逐出作業會在背景執行,因此達到 maxmemory-gb 限制後,金鑰不會立即遭到逐出。如果寫入速率過高,可能會超過金鑰逐出速率,導致記憶體不足。

    Memorystore 執行個體的預設逐出政策為 volatile-lru。如果您使用 volatile-* 撤銷政策,請務必為要過期的金鑰設定存留時間,否則 Redis 無法撤銷任何金鑰。

    如需逐出政策清單,請參閱「Maxmemory 政策」。

    如要瞭解如何變更淘汰政策,請參閱「設定 Redis 執行個體」。

記憶體片段化

  • 記憶體片段化可能會導致 Memorystore 執行個體記憶體不足,即使記憶體用量與記憶體大小的比例很低也是如此。maxmemory-gb當作業系統分配 Redis 無法充分利用的記憶體頁面時,就會發生記憶體片段化,這通常是在重複寫入和刪除作業後發生。這類網頁累積過多可能會導致系統記憶體不足,最終造成 Redis 伺服器當機。activedefrag Redis 設定有助於減少片段。

主動重組

  • Redis 4.0 以上版本提供 activedefrag 設定。如有可能,請使用 Redis 4.0 建立 Memorystore 執行個體。Memorystore 預設會將 activedefrag 設為「否」。將 activedefrag 設為「yes」會導致 CPU 效能降低,但有助於減少記憶體片段化,進而解決記憶體不足問題。

    如果系統記憶體用量比率指標顯示記憶體片段化,請開啟 activedefrag。否則,activedefrag 仍為選用設定。

耗用大量記憶體的作業

下列作業會使用大量記憶體,尤其是與高寫入率搭配執行時:

匯出作業

Memorystore 匯出功能會使用 Redis BGSAVE 作業,視資料大小、寫入量和觸控鍵而定,匯出作業所需的記憶體可能是資料所占空間的兩倍。因此,如要順利匯出,您可能需要在匯出期間將 maxmemory-gb 限制調降至執行個體容量的 50%。

調整規模和版本升級作業

在寫入負載量高的期間擴充升級,可能會因複製作業造成的記憶體負擔,導致執行個體記憶體壓力過大。此外,讀取負載過高可能會增加 Redis 的輸出緩衝區大小,導致記憶體壓力增加。如果擴展或升級作業因記憶體壓力而失敗,請採取下列行動:

  • 在執行擴展/升級作業前,請將 maxmemory-gb 降至執行個體容量的 50%。如果可以,您也應該在執行個體流量較低時調降 maxmemory,因為這樣做可減少調降 maxmemory 對快取命中率造成的負面影響。
  • 在寫入量較低的期間進行擴充/升級。

維護

維護作業也會增加執行個體的記憶體壓力。請採取措施,確保系統記憶體使用率指標在排定維護時間達到 50% 以下。您可以安排在執行個體流量較低的時間進行這項作業,也可以在維護期間暫時調高執行個體大小,讓「系統記憶體用量比率」指標達到 50% 以下。

監控執行個體的記憶體用量

請監控本節所述的指標,並設定快訊。您可以透過這些指標和快訊,深入瞭解執行個體的記憶體用量。如要瞭解如何查看指標及設定快訊,請參閱「監控 Redis 執行個體」。

指標 完整指標地址
Maxmemory redis.googleapis.com/stats/memory/maxmemory
記憶體用量 redis.googleapis.com/stats/memory/usage
記憶體用量比率 redis.googleapis.com/stats/memory/usage_ratio
系統記憶體過載時間 redis.googleapis.com/stats/memory/system_memory_overload_duration
系統記憶體用量比率 redis.googleapis.com/stats/memory/system_memory_usage_ratio
快取命中率 redis.googleapis.com/stats/memory/cache_hit_ratio
設有期限的金鑰 redis.googleapis.com/keyspace/keys_with_expiration
過期的金鑰 redis.googleapis.com/stats/expired_keys
已撤銷的金鑰 redis.googleapis.com/stats/evicted_keys

記憶體用量比率

「記憶體用量比率」指標會指出工作集大小距離 maxmemory-gb 限制還有多遠。除非驅逐政策設為 no-eviction,否則達到 maxmemory 的執行個體資料不一定表示有問題。不過,金鑰逐出作業是需要時間的背景程序。如果寫入率很高,Redis 可能還來不及撤銷金鑰來釋出空間,記憶體就會用盡。

系統記憶體用量比率

系統記憶體用量比率是重要的監控指標。為確保執行個體有足夠的記憶體來支援工作負載和其他耗用大量記憶體的操作,請務必預留足夠的系統記憶體。

設定快訊,讓系統在系統記憶體用量比率達到 80% 時通知您。如果達到 80%,您就應開始密切監控系統記憶體用量比率指標。如果系統記憶體用量比率持續大幅增加,請開啟 activedefrag、降低 maxmemory,並考慮擴充執行個體。

系統記憶體用量比率達到 100% 後,任何會進一步增加執行個體記憶體用量的作業都會遭到封鎖,且 Redis 會傳回下列錯誤:

-OOM command not allowed under OOM prevention.

詳情請參閱「管理系統記憶體用量比率」。

系統記憶體過載時間

如果記憶體用量過高,Memorystore 會封鎖對執行個體的寫入作業,確保執行個體運作正常。系統記憶體過載時間長度 會追蹤執行個體處於寫入作業遭封鎖狀態的時間長度。

您應為這項指標設定快訊,以便在執行個體的寫入作業遭到封鎖時收到通知。此外,您也可以參考這項指標,排解收到 -OOM command not allowed under OOM prevention. 錯誤的問題。

快取命中率

您應定期監控快取命中率,瞭解 Redis 執行個體中的鍵成功傳回鍵查閱的百分比。一般來說,快取命中率越高越好。進行任何大型設定變更 (例如調整 maxmemory-gb 限制、變更逐出政策或擴充執行個體) 之前,請記下快取命中率。然後,在修改執行個體後,再次檢查快取命中率,瞭解變更對這項指標的影響。

設有期限的金鑰和過期的金鑰

Stackdriver 指標「expirable keys」會監控設有期限的金鑰數量。如果沒有設有期限的金鑰,可能表示您未為金鑰設定存留時間。在這種情況下,當執行個體資料達到 maxmemory-gb 限制時,沒有可逐出的鍵,如果您使用 volatile-* 逐出政策,可能會導致記憶體不足。

您也可以監控過期金鑰。如果指標顯示許多過期金鑰,但執行個體仍有記憶體壓力,您應降低 maxmemory-gb

解決記憶體不足的問題

如果執行個體發生記憶體壓力或記憶體不足錯誤,請遵循下列最佳做法。

  1. 如果您使用 volatile-* 逐出政策,請務必為要過期的鍵設定存留時間。詳情請參閱驅逐政策

  2. 適用於執行 Redis 4.0 以上版本的執行個體:

    1. 為執行個體開啟 activedefrag。詳情請參閱「主動重組」一文。
  3. 瞭解如何使用指標解決記憶體不足的問題,並深入瞭解執行個體的記憶體用量:監控執行個體的記憶體用量管理系統記憶體用量比率

  4. 瞭解如何在執行耗用大量記憶體的作業時調整 maxmemory。

  5. 如果「system memory usage ratio」(系統記憶體用量比率) 指標超過 80%,請降低執行個體的 maxmemory-gb 限制。詳情請參閱「管理系統記憶體用量比率」。

  6. 建議擴充執行個體容量

  7. 如果仍遇到 OOM 狀況,請與 Google Cloud Platform 支援團隊聯絡。

選擇適當的 Memorystore 執行個體規模

本節將介紹三種不同的方法,協助您根據工作負載調整執行個體大小:

判斷 Memorystore 執行個體的初始大小

首先,請選擇要使用標準級或基本級執行個體。如要進一步瞭解 Memorystore for Redis 層級,請參閱 Redis 層級功能。為應用程式選取合適的層級後,請按照下列步驟判斷所需的執行個體大小:

  1. 判斷資料大小。

    • 估算應用程式會寫入 Redis 執行個體的金鑰數量和平均大小。將這些值相乘,即可粗略估算所需的執行個體大小。
  2. 選擇逐出政策。

    • 如果您使用 noeviction maxmemory 政策,執行個體大小必須足以容納尖峰工作負載和工作集。如果記憶體不足,執行個體可能會進入記憶體不足狀態。
    • 其他逐出政策不會影響您應佈建的執行個體大小。
  3. 為標準級執行個體佈建額外記憶體

    • 與基本級執行個體不同,標準級執行個體會保留 10% 的執行個體容量做為複製緩衝區。如果選擇標準層級執行個體,請務必採用步驟一的資料估算結果,並為複製緩衝區額外佈建 10% 的容量。
  4. 預估平均和尖峰寫入速率

    • 請盡可能估算應用程式使用的寫入速率和鍵大小。寫入速率與移除金鑰的速率相比,決定了執行個體隨時間成長的速度。
  5. 向上擴充,達到所需的快取命中率

    • 監控快取命中率,如果成功快取命中的次數未達到預期,表示您需要增加執行個體大小,或確保應用程式正在將所要求的鍵寫入 Memorystore 執行個體,而不是未完成的鍵。

判斷執行個體是否因記憶體不足而封鎖寫入作業

如果收到下列錯誤訊息:

-OOM command not allowed under OOM prevention.

然後確認以下事項:

  1. 執行個體發生問題前,系統記憶體用量比率超過 80%。
  2. 在執行個體發生問題前,系統記憶體用量比率快速增加。
  3. 在寫入作業遭到封鎖的同一段時間內,「系統記憶體過載時間」指標顯示的值大於零。

如果是這樣,可能表示執行個體因記憶體不足而封鎖寫入作業。

管理系統記憶體用量比率

設定快訊,讓系統在「system memory ratio」(系統記憶體用量比率) 指標超過 80% 時通知您。如果系統記憶體用量比率超過 80%,您應採取適當行動,避免執行個體記憶體不足。視寫入量和鍵存取模式而定,系統記憶體用量可能會快速增加至 100%。Memorystore 提供下列方式來管理系統記憶體用量比率

  • 針對執行 Redis 4.0 以上版本的執行個體,開啟 activedefrag
  • 降低執行個體的 maxmemory-gb 限制。
  • 調度執行個體資源。
  • 選擇適當的逐出政策。
  • 為易變性金鑰設定存留時間。
  • 手動從執行個體刪除金鑰。

開啟 activedefrag

如果系統記憶體用量比率超過 80%,請開啟 activedefrag (適用於執行 Redis 4.0 以上版本的執行個體)。重組作業可能需要數小時才能釋出記憶體片段。如果寫入流量很高,光是重組可能不足以防止執行個體記憶體不足。因此,您可能需要採取下列建議:

降低執行個體的 maxmemory 限制

如果系統記憶體用量比率超過 80%,您應降低 maxmemory-gb,但請先查看系統記憶體用量比率隨時間的變化,再決定要設定的新 maxmemory-gb 限制。

情境 1:系統記憶體用量比率緩慢上升。這可能是因為記憶體片段化,請以小幅度調降 maxmemory-gb,直到系統記憶體使用率穩定低於 80% 為止。

情境 2:系統記憶體用量比率快速飆升,且執行個體上的寫入負載顯著增加。記憶體密集型作業可能導致用量暴增。在這種情況下,您應以較大的增量調低 maxmemory-gb 限制,確保執行個體不會進入記憶體不足狀態,或能從記憶體不足狀態中復原。請注意,降低 maxmemory 可能會降低執行個體的快取命中率。 如果快取命中率大幅降低,表示您應調高執行個體資源配置,讓應用程式能充分發揮 Redis 的優勢。如要瞭解如何調整 maxmemory-gb 設定,請參閱「設定 Redis 執行個體」。

擴充執行個體

請按照「調度 Redis 執行個體資源」一文中的操作說明,增加執行個體容量。

Maxmemory 縮放範例:

如果執行個體為 10 GB,且 maxmemory-gb 設為 8 GB,則您有 8 GB 可用於儲存金鑰,以及 2 GB 的記憶體負擔。如果將執行個體擴充至 20 GB,maxmemory-gb 會擴充至 16 GB。因此,執行個體現在有 16 GB 的記憶體可儲存金鑰,以及 4 GB 的額外負荷。如需增加或減少執行個體大小的操作說明,請參閱「調整 Redis 執行個體的資源配置」。

選擇適當的逐出政策

如果您要儲存揮發性資料,請選擇其中一項volatile-* 逐出政策。 如果您儲存的資料並非揮發性資料,請選擇其中一項allkeys-*政策。

手動從執行個體刪除金鑰

您可以手動從執行個體刪除鍵,改善記憶體不足的情況。這項暫時性解決方案有助於改善執行個體健康狀態。