本頁面提供最佳化使用 Memorystore for Redis Cluster 的指南。這個頁面也會指出應避免的潛在問題。
記憶體管理最佳做法
本節說明叢集的記憶體管理策略,確保 Memorystore for Redis Cluster 能有效率地為用戶端應用程式運作。
記憶體管理概念
寫入負載 - 在 Redis 叢集上新增或更新金鑰的量和速度。視 Redis 用途和應用程式使用模式而定,寫入負載可能介於正常到非常高之間。
淘汰政策 - Memorystore for Redis Cluster 使用
volatile-lru淘汰政策。您可以使用 EXPIRE 等指令,為鍵設定逐出作業。
監控寫入負載正常的叢集
查看 /cluster/memory/maximum_utilization 指標。如果 /cluster/memory/maximum_utilization 為 100% 或更低,表示 Redis 叢集在正常寫入負載下運作良好。
不過,如果記憶體用量接近 100%,且您預期數據用量會增加,就應擴充叢集大小,為新資料預留空間。
監控寫入負載高的叢集
查看 /cluster/memory/maximum_utilization 指標。視高寫入負載的嚴重程度而定,叢集可能會在下列門檻發生效能問題:
如果
/cluster/memory/maximum_utilization達到 65% 以上,寫入負載過高可能會導致問題。如果
/cluster/memory/maximum_utilization達到 85% 以上,中等偏高的寫入負載可能會發生問題。
在這些情況下,您應擴大叢集大小,以提升效能。
如果遇到問題,或擔心叢集的寫入負載過高,請與Google Cloud 支援團隊聯絡。
調整分片大小
在叢集中調整分片數量時,請在寫入作業較少的期間進行調整。在高寫入負載期間進行資源調度,可能會因複製或時段遷移造成的記憶體負擔,導致叢集記憶體壓力過大。
如果您的 Redis 使用案例會撤銷金鑰,縮減叢集大小可能會降低快取命中率。不過,由於金鑰遭逐出是預期行為,因此您不必擔心資料遺失。
如果 Redis 用途不允許遺失金鑰,您只能縮減至仍有足夠空間儲存資料的較小叢集。新的目標分片數應至少是資料所用記憶體的 1.5 倍。換句話說,您應為叢集中的資料量 1.5 倍,佈建足夠的分片。您可以使用 /cluster/memory/total_used_memory 指標,查看叢集儲存的資料量。
CPU 使用率最佳做法
如果發生非預期的可用區服務中斷,由於無法使用的可用區節點會失去容量,叢集的 CPU 資源就會減少。建議使用高可用性叢集。使用多個分片副本 (而非每個分片一個副本),可在發生中斷時提供額外的 CPU 資源。每個分片最多可有五個副本。
此外,我們建議您管理節點 CPU 使用率,確保節點有足夠的 CPU 額外負擔,可處理因可用區意外中斷而增加的流量。您應使用「主要執行緒 CPU 秒數」/cluster/cpu/maximum_utilization指標,監控主要項目和副本的 CPU 使用率。
視每個節點佈建的副本數量而定,建議採用下列 /cluster/cpu/maximum_utilization CPU 使用率目標:
- 如果叢集每個節點有一個副本,請將主要副本和副本的目標值設為 0.5 秒。
/cluster/cpu/maximum_utilization - 如果叢集每個節點有兩個以上的副本,主要副本的目標值為 0.9 秒,每個副本的目標值為 0.5 秒。
/cluster/cpu/maximum_utilization
如果指標值超過這些建議,建議您增加叢集中的分片數量。如果叢集的副本數量少於五個,您也可以擴增副本數量,最多可達五個副本。
如果叢集的 CPU 使用率偏高,或是叢集資源耗盡 (例如連線過多),叢集可能會發生異常行為,且可能缺少外部指標。
需要大量資源的 Redis 指令
強烈建議您避免使用耗用大量資源的 Redis 指令。使用這些指令可能會導致下列效能問題:
- 延遲時間長和用戶端逾時
- 因指令增加記憶體用量而導致記憶體壓力
- 節點複製和同步處理期間發生資料遺失,因為 Redis 主執行緒遭到封鎖
- 健康狀態檢查資源不足、可觀測性和複製
下表列出耗用大量資源的 Redis 指令示例,並提供節省資源的替代方案。
| 類別 | 耗用大量資源的指令 | 資源效率較高的替代方案 |
|---|---|---|
| 針對整個鍵空間執行 | KEYS |
SCAN |
| 針對可變長度鍵集執行 | LRANGE |
限制查詢所用範圍的大小。 |
ZRANGE |
限制查詢所用範圍的大小。 | |
HGETALL |
HSCAN |
|
SMEMBERS |
SSCAN |
|
| 封鎖指令碼執行作業 | EVAL |
確認指令碼不會無限期執行。 |
EVALSHA |
確認指令碼不會無限期執行。 | |
| 移除檔案和連結 | DEL |
UNLINK |
| 發布及訂閱 | PUBLISH |
SPUBLISH |
SUBSCRIBE |
SSUBSCRIBE |
Redis 用戶端最佳做法
連線至叢集時,應用程式必須使用叢集感知 Redis 用戶端。如需叢集感知型用戶端和範例設定的範例,請參閱「用戶端程式庫程式碼範例」。用戶端必須維護叢集中雜湊值區與對應節點的對應,才能將要求傳送至正確的節點,並避免叢集重新導向造成的效能負擔。
用戶端對應
在下列情況下,客戶必須取得完整的時段清單和對應節點:
初始化用戶端時,必須填入節點對應的初始時段。
當伺服器傳送
MOVED重新導向時,例如在容錯移轉情況下,當前主要節點服務的所有時段都由副本接管,或重新分片時,時段會從來源主要節點移至目標主要節點。當伺服器傳回
CLUSTERDOWN錯誤,或連線至特定伺服器時持續發生逾時問題。伺服器傳回
READONLY錯誤時,如果主要節點降級為副本,就可能發生這種情況。此外,用戶端應定期重新整理拓撲,讓用戶端保持暖機狀態,以因應任何變更,並瞭解可能不會導致伺服器重新導向或發生錯誤的變更,例如新增副本節點時。請注意,也應關閉任何過時的連線,做為拓撲重新整理的一部分,以減少在指令執行階段處理連線失敗的需求。
發掘客戶
用戶端通常會向 Redis 伺服器發出 CLUSTER SLOT、CLUSTER NODE 或 CLUSTER SHARDS 指令,進行用戶端探索。建議使用 CLUSTER SHARDS 指令。CLUSTER SHARDS 會取代 CLUSTER SLOTS 指令 (已淘汰),提供更有效率且可擴充的叢集表示法。
叢集用戶端探索指令的回覆大小會因叢集大小和拓撲而異。節點較多的大型叢集會產生較大的回應。因此,請務必確保執行叢集拓撲探索的用戶端數量不會無限增加。
這些拓撲重新整理作業會耗用大量 Redis 伺服器資源,但對應用程式可用性而言非常重要。因此,請務必確保每個用戶端在任何時間點都只發出單一探索要求 (並將結果快取在記憶體中),且發出要求的用戶端數量受到限制,以免伺服器過載。
舉例來說,當用戶端應用程式啟動或與伺服器失去連線,且必須執行叢集探索時,常見的錯誤是用戶端應用程式會發出多個重新連線和探索要求,但不會在重試時加入指數輪詢。這可能會導致 Redis 伺服器長時間沒有回應,並造成極高的 CPU 使用率。
避免 Redis 上的探索作業過載
為減輕連線和探索要求突然湧入所造成的影響,建議採取下列做法:
實作大小有限且較小的用戶端連線集區,以限制用戶端應用程式的並行傳入連線數量。
如果用戶端因逾時而與伺服器中斷連線,請使用指數輪詢和隨機延遲重試。避免多個用戶端同時對伺服器造成負擔。
使用 Memorystore for Redis Cluster 探索端點執行叢集探索。探索端點具備高可用性,且叢集內所有節點都會進行負載平衡。此外,探索端點會嘗試將叢集探索要求轉送至具有最新拓撲檢視畫面的節點。
偵測及處理沒有回應的連線
強烈建議您設定用戶端應用程式,偵測與 Memorystore for Redis Cluster 的連線是否沒有回應。系統偵測到連線沒有回應時,用戶端必須重設連線。如要建構彈性應用程式,建議採用下列用戶端設定:
- 設定 TCP keep-alive 參數:設定
TCP keepalive time、TCP keepalive interval和TCP keepalive probes參數,讓用戶端主動偵測並捨棄沒有回應的連線,即使連線處於閒置狀態也一樣。舉例來說,如果將TCP keepalive time參數設為 30 秒、TCP keepalive interval設為 10 秒,且TCP keepalive probes設為 3,則用戶端會在 1 分鐘內重設無回應的閒置連線。 - 設定 TCP 使用者逾時:在用戶端中設定這個逾時時間,即可重設有待處理要求且停止回應的連線。舉例來說,如果將逾時時間設為 15 秒,用戶端就會在 15 秒後重設有待處理要求的無回應連線。
持續性最佳做法
本節說明持續性的最佳做法。
RDB 持久性與新增副本
如要使用 RDB 快照備份叢集,或在叢集中新增副本,建議採用下列最佳做法:
記憶體管理
RDB 快照會使用程序分叉和「寫入時複製」機制,擷取節點資料的快照。視節點的寫入模式而定,節點使用的記憶體會隨著寫入觸及的頁面遭到複製而增加。記憶體用量最多可達節點中資料大小的兩倍。
為確保節點有足夠的記憶體可完成快照,請將 maxmemory 保留或設為節點容量的 80%,以便預留 20% 的額外空間。除了監控快照,這項記憶體額外負擔也有助於管理工作負載,確保快照順利建立。此外,新增副本時,請盡可能降低寫入流量。詳情請參閱「監控寫入負載高的叢集」。
過時的快照
從過時快照還原節點可能會導致應用程式發生效能問題,因為應用程式會嘗試調解大量過時的鍵,或資料庫的其他變更 (例如結構定義變更)。如果您擔心從過時的快照還原,可以停用 RDB 持續性功能。重新啟用持續性後,系統會在下一個排定的快照間隔建立快照。
RDB 快照對效能的影響
視工作負載模式而定,RDB 快照可能會影響叢集效能,並增加應用程式的延遲時間。如果可以接受較不頻繁的快照,您可以安排在叢集流量較低的時段執行 RDB 快照,盡量減少對效能的影響。
舉例來說,如果叢集在凌晨 1 點到 4 點的流量較低,您可以將開始時間設為凌晨 3 點,間隔設為 24 小時。
如果系統負載量持續不變,且需要頻繁建立快照,請仔細評估效能影響,並權衡使用 RDB 快照對工作負載的好處。
新增副本
新增副本時,需要 RDB 快照。如要進一步瞭解 RDB 快照,請參閱「記憶體管理」一文。
使用單一可用區叢集的時機
如果您將叢集設定為不使用副本,建議您使用單一可用區叢集。原因如下:
費用和效能
如果您的主要目標是盡量降低成本,並為位於相同區域的用戶端提供最高效能,建議您選擇單一可用區叢集。
將服務中斷的影響降至最低
選擇單一可用區叢集時,區域性中斷較不會影響叢集。將所有節點放在單一區域內,區域性服務中斷影響伺服器的機率就會從 100% 降至 33%。叢集所在區域發生故障的機率為 33%,而位於無法使用的區域中的節點受到影響的機率則為 100%。
快速復原
如果單一可用區叢集發生可用區中斷情形,Memorystore for Redis Cluster 會簡化資料復原程序。您可以在運作中的可用區快速佈建新叢集,並重新導向應用程式,盡量減少作業中斷。
Lettuce 最佳做法
本節說明使用 Lettuce 連線至叢集的最佳做法。
更新參數值
使用 Lettuce 時,請將 validateClusterNodeMembership 參數變更為 false。否則,拓撲變更時可能會發生 unknownPartition 錯誤。
啟用傳輸層安全標準 (TLS)
本節說明使用傳輸層安全標準 (TLS) 的安全性優點和效能影響,並提供啟用建議。
安全防護優勢
使用 TLS 可享有下列安全性優點:
- 身分與存取權管理 (IAM) 驗證:傳輸層安全標準 (TLS) 會使用這類驗證來防範伺服器詐騙攻擊,例如中間人攻擊。
- 傳輸加密: Google Cloud的內建加密功能可在基礎架構層級保護 Google 網路內的流量。不過,這需要信任 Google 的主機和網路堆疊。雖然這項加密功能預設為啟用,且使用者不會察覺,但並非端對端加密。另一方面,TLS 則是在應用程式層使用傳輸中資料加密。這種端對端加密方式可讓您進一步控管加密金鑰和程序。
- 驗證權杖保護:如果您使用 IAM 驗證,啟用 TLS 可將驗證權杖曝光和洩漏的風險降至最低。
效能影響
傳輸層安全標準 (TLS) 會對效能造成以下影響:
建立連線: 建立 TLS 工作階段的用戶端和伺服器可以繼續執行工作階段,不必重複建立用戶端與伺服器連線的資源密集程序。啟用 TLS 續傳功能後,即可減少用戶端與伺服器之間建立連線的額外負擔。
如果未建立 TLS 續傳機制,建立連線會耗用大量資源。無論是新連線還是現有連線,用戶端與伺服器之間的多個連線都可能導致連線逾時。這可能會造成雪球效應,因為 Memorystore for Redis Cluster 會嘗試重新建立連線逾時的連線,進而增加建立連線時使用的資源。
加密及解密資料: 資料加密及解密作業需要大量 CPU 資源,因此會對用戶端和伺服器造成影響。這可能會降低叢集的容量,並增加叢集的延遲時間。
建議
考慮是否啟用 TLS 時,建議您評估安全性政策,同時考量 TLS 的優缺點。如果您選擇啟用 TLS,請注意下列事項:
- 啟用 TLS 續傳功能可減輕建立連線的作業負擔。用戶端與伺服器之間只需要建立初始連線,不過,如果用戶端的叢集大小突然擴大,可能會導致短暫中斷,這是因為每個新用戶端主機都會進行初始完整交握。
- 雖然部分用戶端程式庫可能未提供內建控制項來啟用 TLS,但您可以使用自訂程式碼,將這項功能整合至叢集。