記憶體管理最佳做法

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

本主題說明:

記憶體管理概念

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

執行個體容量

maxmemory 設定

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

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

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

系統記憶體用量比率

  • 您可以使用「系統記憶體用量比率」指標,評估執行個體相對於系統記憶體的記憶體用量。Memorystore 會自動管理系統記憶體,以便處理因記憶體密集作業和開放原始碼 Redis 常見的記憶體碎裂現象而導致的記憶體用量激增情形。

    如果系統記憶體用量比率指標超過 80%,表示執行個體處於記憶體壓力下,您應按照「管理系統記憶體用量比率」一文中的指示操作。如果您沒有採取行動,記憶體用量持續增加,執行個體可能會因記憶體不足而異常終止。由於記憶體碎裂,系統記憶體用量比率指標可能會超過 80%。或者,如果指標迅速飆升至 80% 以上,表示您可能使用了記憶體密集作業之一。

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

已使用的記憶體

  • 「used memory」指標會顯示 Memorystore 執行個體中的資料量。執行個體的已用記憶體可增加至 maxmemory-gb 設定上限。當已用記憶體超過 maxmemory-gb 限制時,移除政策就會生效。

驅逐政策

  • 當執行個體資料達到 maxmemory-gb 上限時,執行個體的撤銷政策 (也稱為 Maxmemory 政策) 會決定 Redis 撤銷金鑰的方式。Redis 會在正常快取用途中淘汰金鑰。鍵淘汰作業會以背景程序執行,因此鍵不會在達到 maxmemory-gb 限制後立即淘汰。高寫入率可能會導致鍵值淘汰速度不及,進而導致記憶體不足的狀況。

    Memorystore 執行個體的預設淘汰政策為 volatile-lru。如果您使用 volatile-* 撤銷政策,請務必為要過期的金鑰設定存留時間,否則 Redis 就沒有要撤銷的金鑰。

    如需清除政策的清單,請參閱「Maxmemory 政策」。

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

記憶體碎裂

  • 即使已使用的記憶體與 maxmemory-gb 的比率偏低,記憶體碎裂仍可能導致 Memorystore 執行個體記憶體不足。當作業系統分配 記憶體頁面,而 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

記憶體用量比率

「memory usage ratio」指標會顯示工作集大小距離 maxmemory-gb 上限有多近。除非將淘汰政策設為不淘汰,否則達到 maxmemory 的執行個體資料不一定表示有問題。不過,鍵值淘汰是需要時間的背景程序。如果寫入率很高,在 Redis 有時間撤銷金鑰釋出空間之前,記憶體就可能用盡。

系統記憶體用量比率

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

設定快訊,讓系統在「systsem memory ratio」(系統記憶體用量比率) 指標達到 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」會監控設定到期日的金鑰數量。如果沒有設有期限的金鑰,可能表示您沒有為金鑰設定存留時間。在這種情況下,如果您使用 volatile-* 淘汰政策,當執行個體資料達到 maxmemory-gb 上限時,就沒有可淘汰的鍵,可能會導致記憶體不足的情況。

您還可以監控到期金鑰這項指標。如果指標顯示許多已過期的鍵,但執行個體仍出現記憶體壓力,您應降低 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 政策,執行個體大小必須足夠大,才能容納最高工作負載和工作集。如果您在使用此 maxmemory 政策時耗盡記憶體,執行個體就會進入記憶體不足的狀態。
    • 其他淘汰政策不會影響您應配置的執行個體大小。
  3. 為標準級執行個體配置額外記憶體

    • 與基本級執行個體不同,標準級執行個體會保留 10% 的執行個體容量做為複製緩衝區。如果您選擇標準層級執行個體,請務必根據步驟 1 的資料估計值,為複製緩衝區額外配置 10%。
  4. 預估平均和高峰寫入率

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

    • 請監控快取命中率,如果快取命中率不如預期,表示您需要增加執行個體大小,或是確保應用程式會將索引鍵寫入要求的 Memorystore 執行個體,而非未完成。

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

如果收到下列錯誤訊息:

-OOM command not allowed under OOM prevention.

然後檢查以下事項:

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

如果是這樣,則表示執行個體因記憶體不足而阻斷寫入作業。

管理系統記憶體用量比率

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

  • 針對執行 Redis 4.0 以上版本的執行個體,開啟 activedefrag
  • 降低執行個體的 maxmemory-gb 限制。
  • 擴充執行個體。
  • 選擇適當的淘汰政策。
  • 為易變性金鑰設定 TTL。
  • 手動從執行個體中刪除金鑰。

開啟 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 執行個體」一文的操作說明,增加執行個體容量。

最大記憶體調整範例:

如果您有 10 GB 的執行個體,且 maxmemory-gb 設為 8 GB,則您有 8 GB 可用於儲存金鑰,以及 2 GB 的記憶體開銷。如果將執行個體調整為 20 GB,maxmemory-gb 會調整為 16 GB。因此,您的執行個體現在有 16 GB 的記憶體可用於儲存金鑰,以及 4 GB 的額外負擔。如要瞭解如何增加或減少執行個體的大小,請參閱「調整 Redis 執行個體」一文。

選擇適當的退租政策

如果您要儲存易變的資料,請選擇其中一個 volatile-* evict 政策。如果您儲存的資料不會變動,請選擇其中一個 allkeys-* 政策。

手動從執行個體中刪除金鑰

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