記憶體管理最佳做法

如果未正確管理及設定 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 設為「no」。將 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-* 逐出政策,請務必針對要過期的鍵設定 TTL。詳情請參閱「逐出政策」。

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

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

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

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

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

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

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

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

決定 Memorystore 執行個體的初始大小

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

  1. 判斷資料大小。

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

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

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

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

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

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

如果收到下列錯誤訊息:

-OOM command not allowed under OOM prevention.

然後確認:

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

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

管理系統記憶體用量比率

設定快訊,讓系統在「system memory usage 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-*政策。

手動從執行個體刪除金鑰

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