Memorystore for Valkey のベスト プラクティス

このページでは、Memorystore for Valkey を最適に使用するためのガイダンスを提供します。このページでは、回避すべき潜在的な問題についても説明します。

メモリ管理のベスト プラクティス

このセクションでは、Memorystore for Valkey がアプリケーションで効率的に動作するようにインスタンス メモリを管理する戦略について説明します。

メモリ管理のコンセプト

  • メモリ使用量: インスタンスが使用するメモリの量。メモリ容量は固定されています。指標を使用して、使用しているメモリ量をモニタリングできます。

  • 強制排除ポリシー: Memorystore for Valkey は volatile-lru 強制排除ポリシーを使用します。EXPIRE コマンドなどの Valkey コマンドを使用して、キーの強制排除を設定できます。

インスタンスのメモリ使用量をモニタリングする

Memorystore for Valkey インスタンスのメモリ使用量をモニタリングするには、/instance/memory/maximum_utilization 指標を表示することをおすすめします。インスタンスのメモリ使用量が 80% に近づき、データ使用量の増加が予想される場合は、インスタンスのサイズをスケールアップして、新しいデータ用のスペースを確保します。

インスタンスのメモリ使用量が多い場合は、次の操作を行ってパフォーマンスを改善します。

問題が発生した場合は、Google Cloud カスタマーケアにお問い合わせください。

クラスタモードが有効な場合にシャードをスケーリングする

インスタンスのシャード数をスケーリングする場合は、書き込みが少ない期間にスケーリングすることをおすすめします。使用率が高い期間にスケーリングを行うと、レプリケーションやスロットの移行によるメモリのオーバーヘッドが原因で、インスタンスにメモリの負荷がかかります。

Valkey のユースケースでキーの強制排除を使用している場合、より小さいインスタンス サイズにスケーリングすると、キャッシュ ヒット率が低下する可能性があります。ただし、この状況では、キーの強制排除が想定されるため、データの損失を心配する必要はありません。

キーを失いたくない Valkey のユースケースでは、データを格納するのに十分な容量がある、より小さいインスタンスにのみスケールダウンする必要があります。新しいターゲット シャード数は、データで使用されるメモリの 1.5 倍以上にする必要があります。つまり、インスタンス内のデータ量の 1.5 倍に十分なシャードをプロビジョニングする必要があります。/instance/memory/total_used_memory 指標を使用すると、インスタンスに保存されているデータの量を確認できます。

CPU 使用率のベスト プラクティス

予期しないゾーンの停止が発生すると、利用できないゾーンのノードから容量が失われるため、インスタンスの CPU リソースが減少します。高可用性インスタンスを使用することをおすすめします。シャードごとに複数のレプリカを使用すると(シャードごとに 1 つのレプリカを使用する場合とは異なり)、停止中に追加の CPU リソースが提供されます。シャードごとに最大 5 個のレプリカを使用できます。

また、予期しないゾーンの停止が発生した場合に、失われた容量からの追加トラフィックを処理するのに十分な CPU オーバーヘッドがノードに確保されるように、ノードの CPU 使用率を管理することをおすすめします。メインスレッド CPU 秒 /instance/cpu/maximum_utilization 指標を使用して、プライマリとレプリカの CPU 使用率をモニタリングする必要があります。

ノードごとにプロビジョニングするレプリカの数に応じて、次の /instance/cpu/maximum_utilization CPU 使用率の目標値をおすすめします。

  • ノードごとに 1 つのレプリカを持つインスタンスの場合、/instance/cpu/maximum_utilization 値の目標はプライマリで 0.5 秒、レプリカで 0.5 秒です。
  • ノードあたり 2 つ以上のレプリカを持つインスタンスの場合、/instance/cpu/maximum_utilization 値の目標はプライマリで 0.9 秒、各レプリカで 0.5 秒です。

指標の値がこれらの推奨値を超えている場合は、インスタンスのシャード数をスケールアップすることをおすすめします。インスタンスのレプリカ数が 5 個未満の場合は、レプリカ数を最大 5 個までスケールアップすることもできます。

インスタンスの CPU 使用率が高い場合や、インスタンスのリソースが枯渇している場合(接続数が多すぎる場合など)、インスタンスが誤動作し、外部指標が欠落する可能性があります。

リソースを大量に消費する Valkey コマンド

リソースを大量に消費する Valkey コマンドは使用しないことを強くおすすめします。これらのコマンドを使用すると、次のようなパフォーマンスの問題が発生する可能性があります。

  • 高レイテンシとクライアント タイムアウト
  • メモリ使用量を増加させるコマンドが原因のメモリ不足
  • Valkey メインスレッドがブロックされているため、ノードのレプリケーションと同期中にデータが失われる
  • ヘルスチェック、オブザーバビリティ、レプリケーションの枯渇

次の表に、リソースを大量に消費する Valkey コマンドの例と、リソース効率の高い代替コマンドを示します。

カテゴリ リソースを大量に消費するコマンド リソース効率の高い代替手段
キースペース全体に対して実行する KEYS SCAN
可変長鍵セットに対して実行する LRANGE クエリに使用する範囲のサイズを制限します。
ZRANGE クエリに使用する範囲のサイズを制限します。
HGETALL HSCAN
SMEMBERS SSCAN
スクリプトの実行をブロックする EVAL スクリプトが無期限に実行されないようにします。
EVALSHA スクリプトが無期限に実行されないようにします。
ファイルとリンクを削除する DELETE UNLINK
パブリッシュとサブスクライブ PUBLISH SPUBLISH
SUBSCRIBE SSUBSCRIBE

スケーリングしきい値のベスト プラクティス

スケーリングしきい値のシナリオは、次のカテゴリに分類されます。

  • メモリ使用率のスケーリング
  • CPU 使用率に基づくスケーリング
  • ホットスポットを軽減するためのスケーリング

ワークロードがキーの強制排除に依存している場合、CPU 使用率またはメモリ使用率のスケールインはおすすめしません。これらのワークロードでは、メモリ使用量が最大容量に達してから、エビクションが自動的に発生することがよくあります。その結果、メモリの急増によりスケールイン オペレーションがブロックされます。

以降のセクションでは、スケーリングが必要となる一般的なシナリオと指標のしきい値について詳しく説明します。

メモリ使用率のスケーリング

メモリ使用量に基づいてスケーリングするタイミングを判断するには、/instance/memory/average_utilization 指標と /instance/memory/maximum_utilization 指標をモニタリングします。これらの指標の詳細については、サポートされているモニタリング指標をご覧ください。

インスタンスが次のいずれかの条件を満たしている場合は、スケールアウト オペレーションのトリガーを検討してください。

  • インスタンスの平均メモリ使用率が、推奨されるしきい値の 70% を超えています。
  • 最大メモリ使用率が 80% を超え、平均メモリ使用率が 50% を超えている。

インスタンスが次のいずれかの条件を満たしている場合は、スケールイン オペレーションをトリガーすることを検討してください。

  • インスタンスの平均メモリ使用率が、推奨されるしきい値の 50% を下回っている。
  • 最大メモリ使用率が 60% を下回り、平均メモリ使用率が 40% を下回る。

CPU 使用率に基づくスケーリング

CPU 使用率に基づいてスケーリングするタイミングを判断するには、/instance/cpu/average_utilization 指標と /instance/cpu/maximum_utilization 指標をモニタリングします。

インスタンスが次のいずれかの条件を満たしている場合は、スケールアウト オペレーションのトリガーを検討してください。

  • インスタンスの平均 CPU 使用率が、推奨されるしきい値の 70% を超えています。
  • 最大 CPU 使用率が 80% を超え、平均 CPU 使用率が 50% を超えている。

インスタンスが次のいずれかの条件を満たしている場合は、スケールイン オペレーションをトリガーすることを検討してください。

  • インスタンスの平均 CPU 使用率が、推奨されるしきい値の 50% を下回った。
  • 最大 CPU 使用率が 60% を下回り、平均 CPU 使用率が 40% を下回った。

ホットスポットを軽減するためのスケーリング

Memorystore for Valkey には、同じ指標の平均と最大のバリエーションが用意されています。これらを使用して、その指標ファミリーのホットスポットを特定できます。最大値は最も負荷の高いインスタンス ノードを表し、平均値はインスタンス全体の負荷を表します。最大値が平均値よりも大幅に高い場合は、特定のノードが不均衡に読み込まれている(ホットスポット)ことを示します。この問題を解決するには、インスタンスをスケールアウトすることをおすすめします。詳細については、インスタンス容量をスケーリングするをご覧ください。

平均変動と最大変動の間に大きな差異が見られる場合は、インスタンス ノードに対して INFO memory コマンドと INFO cpu コマンドを実行して、インスタンスから直接リアルタイム データを収集できます。これらのコマンドの使用方法については、Valkey ドキュメントの INFO をご覧ください。

Valkey クライアントのベスト プラクティス

Valkey での接続の過負荷を回避する

接続の急増による影響を軽減するには、次のことをおすすめします。

  • 最適なクライアント接続プールサイズを決定します。各クライアントの適切な開始サイズは、Valkey ノードごとに 1 つの接続です。次に、ベンチマークを実行して、接続数を増やしても最大接続数に達しないかどうかを確認します。

  • サーバーがタイムアウトしたためにクライアントがサーバーから切断された場合は、ジッター付きの指数バックオフを使用して再試行します。これにより、複数のクライアントが同時にサーバーに過負荷をかけることを回避できます。

応答しない接続を検出して処理する

Memorystore for Valkey への応答しない接続を検出するようにクライアント アプリケーションを構成することを強くおすすめします。応答しない接続が検出された場合、クライアントは接続をリセットする必要があります。復元力のあるアプリケーションを構築するには、次のクライアント構成をおすすめします。

  • 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 秒後に未処理のリクエストがある応答しない接続をリセットします。

クラスタモードが有効なインスタンスの場合

Memorystore for Valkey クラスタモード対応インスタンスに接続する場合、アプリケーションはクラスタ対応の Valkey クライアントを使用する必要があります。クラスタ対応クライアントの例と構成例については、クライアント ライブラリのコードサンプルをご覧ください。クライアントは、リクエストを正しいノードに送信するために、ハッシュスロットとインスタンス内の対応するノードのマッピングを維持する必要があります。これにより、リダイレクトによるパフォーマンスのオーバーヘッドを回避できます。

クライアント マッピング

クライアントは、次の状況でスロットとマッピングされたノードの完全なリストを取得する必要があります。

  • クライアントが初期化されると、初期スロットをノード マッピングに入力する必要があります。

  • サーバーから MOVED リダイレクトを受信した場合。たとえば、以前のプライマリ ノードによって提供されたすべてのスロットがレプリカによって引き継がれるフェイルオーバーの状況や、スロットがソース プライマリからターゲット プライマリ ノードに移動される際の再シャーディングの状況などです。

  • サーバーから CLUSTERDOWN エラーが返された場合、または特定のサーバーへの接続がタイムアウトし続ける場合。

  • サーバーから READONLY エラーが返された場合。これは、プライマリがレプリカに降格された場合に発生する可能性があります。

  • また、クライアントはトポロジを定期的に更新して、変更に備えてクライアントをウォームアップし、サーバーからのリダイレクトやエラーが発生しない変更(新しいレプリカノードが追加された場合など)を認識する必要があります。コマンドの実行中に失敗した接続を処理する必要性を減らすため、トポロジの更新の一環として、古い接続も閉じる必要があります。

クライアントの開拓

クライアントの検出は通常、Valkey サーバーに SLOTS、NODES、または CLUSTER SHARDS コマンドを発行して行われます。CLUSTER SHARDS コマンドを使用することをおすすめします。CLUSTER SHARDS は、インスタンスのより効率的で拡張可能な表現を提供することで、SLOTS コマンド(非推奨)を置き換えます。

クライアント検出コマンドのレスポンスのサイズは、インスタンスのサイズとトポロジによって異なります。ノード数が多い大規模なインスタンスほど、レスポンスが大きくなります。そのため、ノード トポロジの検出を行うクライアントの数が無制限に増加しないようにすることが重要です。

これらのノード トポロジの更新は Valkey サーバーで高コストですが、アプリケーションの可用性にとっても重要です。したがって、各クライアントが任意の時点で 1 つの検出リクエストを行い(結果をメモリにキャッシュする)、リクエストを行うクライアントの数を制限してサーバーの過負荷を回避することが重要です。

たとえば、クライアント アプリケーションが起動するか、サーバーからの接続が失われ、ノード検出を実行する必要がある場合、クライアント アプリケーションが再試行時に指数バックオフを追加せずに、複数の再接続リクエストと検出リクエストを行うことがよくあります。これにより、Valkey サーバーが長時間応答しなくなり、CPU 使用率が非常に高くなる可能性があります。

ノードの検出に検出エンドポイントを使用する

Memorystore for Valkey の検出エンドポイントを使用してノード検出を実行します。ディスカバリ エンドポイントは高可用性であり、インスタンス内のすべてのノードでロード バランシングされます。さらに、検出エンドポイントは、最新のトポロジビューを持つノードにノード検出リクエストをルーティングしようとします。

クラスタモードが無効になっているインスタンスの場合

アプリケーションがクラスタモードが無効なインスタンスに接続する場合、アプリケーションはプライマリ エンドポイントに接続してインスタンスに書き込み、最新の書き込みを取得する必要があります。アプリケーションは、リーダー エンドポイントに接続してレプリカから読み取り、プライマリ ノードからトラフィックを分離することもできます。

クラスタモードが無効になっているインスタンスにはシャードが 1 つしかないため、インメモリ トポロジは使用されません。したがって、トポロジの更新は適用されません。

フェイルオーバーやメンテナンス イベントの発生中は、インスタンスへの接続が切断されます。これらのイベント後にアプリケーションが正常に再接続されるようにするには、指数バックオフを使用する再試行メカニズムを実装します。

インスタンスのメンテナンスを行う場合は、create-before-destroy 戦略を使用できます。この戦略の詳細については、破棄前の作成ライフサイクル戦略をご覧ください。

この戦略を使用すると、次のエラー メッセージが表示されることがあります。

READONLY You can't write against a read only replica.

この問題を解決するには、インスタンスへの接続を停止します。その後、接続を再作成します。

永続性のベスト プラクティス

このセクションでは、永続性に関するベスト プラクティスについて説明します。

RDB 永続性とレプリカの追加

RDB スナップショットを使用してインスタンスをバックアップする場合、またはインスタンスにレプリカを追加する場合、最適な結果を得るには、次のベスト プラクティスに従ってください。

メモリ管理

RDB スナップショットは、プロセス フォークと「コピーオンライト」メカニズムを使用して、インスタンスのスナップショットを作成します。ノードへの書き込みパターンに応じて、書き込みによってアクセスされたページがコピーされると、ノードの使用メモリが増加します。メモリ使用量は、ノード内のデータの最大 2 倍になることがあります。

ノードにスナップショットを完了するのに十分なメモリがあることを確認するには、maxmemory をノード容量の 80% に維持または設定して、20% がオーバーヘッド用に予約されるようにします。スナップショットのモニタリングに加え、このメモリ オーバーヘッドにより、ワークロードのスナップショットを正常に処理できます。また、レプリカを追加するときは、書き込みトラフィックをできるだけ減らしてください。詳細については、インスタンスのメモリ使用量をモニタリングするをご覧ください。

古いスナップショット

古いスナップショットからノードを復元すると、大量の古くなったキー、またはスキーマの変更などのデータベースに対するその他の変更を調整しようとするため、アプリケーションのパフォーマンスに問題が発生する可能性があります。古いスナップショットからの復元が懸念される場合は、RDB 永続性機能を無効にできます。永続性を再度有効にすると、次のスケジュールされたスナップショット間隔でスナップショットが作成されます。

RDB スナップショットのパフォーマンスへの影響

ワークロード パターンによっては、RDB スナップショットがインスタンスのパフォーマンスに影響し、アプリケーションのレイテンシが増加する可能性があります。スナップショットの頻度を低くしても問題がない場合は、インスタンス トラフィックが少ない期間に実行するようにスケジュールすることで、RDB スナップショットのパフォーマンスへの影響を最小限に抑えることができます。

たとえば、インスタンスのトラフィックが午前 1 時から午前 4 時まで少ない場合は、開始時刻を午前 3 時に設定し、間隔を 24 時間に設定します。

システムの負荷が一定で、スナップショットが頻繁に必要な場合は、パフォーマンスへの影響を慎重に評価し、ワークロードに RDB スナップショットを使用するメリットを比較検討することをおすすめします。

レプリカを追加する

レプリカを追加するには、RDB スナップショットが必要です。RDB スナップショットの詳細については、メモリ管理をご覧ください。

シングルゾーン インスタンスを使用する場合

レプリカを使用しないようにインスタンスを構成する場合は、単一ゾーン インスタンスを使用することをおすすめします。その理由は次のとおりです。

費用とパフォーマンス

費用を最小限に抑え、同じリージョンにあるクライアントのパフォーマンスを最大化することが主な目的である場合は、シングルゾーン インスタンスを選択することをおすすめします。

サービス停止の影響を最小限に抑える

シングルゾーン インスタンスを選択すると、ゾーンの停止がインスタンスに影響する可能性が低くなります。すべてのノードを単一のゾーンに配置すると、ゾーンの停止がサーバーに影響する可能性が 100% から 33% に低下します。インスタンスが配置されているゾーンが停止する確率は 33% です。これに対して、使用できないゾーンに配置されているノードが影響を受ける確率は 100% です。

迅速な回復

シングルゾーン インスタンスでゾーンが停止した場合、Memorystore for Valkey はデータの復元を効率化します。機能しているゾーンに新しいインスタンスを迅速にプロビジョニングし、アプリケーションをリダイレクトして、中断を最小限に抑えることができます。

キャパシティ プランニングのベスト プラクティス

リソースを正常にプロビジョニングし、復元力のあるアーキテクチャを構築できるように、次のキャパシティ プランニングのベスト プラクティスをおすすめします。

  • 複数のロケーションにデプロイする: 一時的なリソースの制約により、優先ゾーンにインスタンスを作成できない場合は、同じリージョン内の別のゾーンまたは別のリージョンにインスタンスを作成してみてください。
  • クロスリージョン アクセスを使用する: 異なるリージョンにあるインスタンスにアクセスするようにクライアントを構成します。ローカル リソースの制約により、別のリージョンにあるインスタンスをプロビジョニングする必要がある場合は、クライアントがインスタンスに接続できます。
  • クロスリージョン レプリケーションを使用する: 障害復旧のために、代替リージョンのセカンダリ インスタンスをプライマリ読み取りまたは書き込みインスタンスにプロモートするには、スイッチオーバーを実行します。

Transport Layer Security(TLS)を有効にする

このセクションでは、Transport Layer Security(TLS)を使用する際のセキュリティ上のメリットとパフォーマンスへの影響について説明します。また、TLS を有効にする際の推奨事項についても説明します。

セキュリティ上のメリット

TLS を使用すると、次のようなセキュリティ上のメリットが得られます。

  • Identity and Access Management(IAM)認証: TLS は、このタイプの認証を使用して、中間者攻撃などのサーバーなりすまし攻撃から保護します。
  • 転送中の暗号化:Google Cloudの組み込み暗号化により、Google のネットワーク内のトラフィックがインフラストラクチャ レベルで保護されます。ただし、これには Google のホストとネットワーク スタックの両方を信頼する必要があります。この暗号化は透過的で、デフォルトで有効になっていますが、エンドツーエンドではありません。一方、TLS はアプリケーション レイヤで転送中の暗号化を使用します。このエンドツーエンドの暗号化により、暗号鍵とプロセスをより詳細に制御できます。
  • 認証トークンの保護: IAM 認証を使用する場合、TLS を有効にすると、認証トークンの公開や漏洩のリスクを最小限に抑えることができます。

パフォーマンスへの影響

TLS は、次のようにパフォーマンスに影響します。

  • 接続を確立する: TLS セッションを確立したクライアントとサーバーは、クライアントとサーバー間の接続を確立するリソースを大量に消費するプロセスを繰り返すことなく、セッションを再開できます。TLS 再開を有効にすると、クライアントとサーバー間の接続を確立する際のオーバーヘッドが削減されます。

    TLS 再開を確立しない場合、接続の確立はリソースを大量に消費します。新規接続と既存接続の両方で、クライアントとサーバー間の接続が多数あると、接続タイムアウトが発生する可能性があります。Memorystore for Valkey はタイムアウトした接続を再確立しようとするため、接続の確立に使用するリソースが増加し、雪だるま式に影響が拡大する可能性があります。

  • データの暗号化と復号: データの暗号化と復号には、クライアントとサーバーの両方に影響する CPU 負荷の高いオペレーションが含まれます。これにより、インスタンスの容量が減少し、インスタンスのレイテンシが増加する可能性があります。

推奨事項

TLS を有効にするかどうかを検討する際は、TLS のメリットとデメリットを考慮しながら、セキュリティ ポリシーを評価することをおすすめします。TLS を有効にする場合は、次の点を考慮してください。

  • TLS 再開を有効にすると、接続を確立するためのオーバーヘッドが軽減されます。クライアントとサーバー間の接続は、初期接続にのみ必要です。ただし、クライアントのインスタンス サイズが急激に拡大すると、新しいクライアント ホストの最初のフル ハンドシェイクによって、一時的な中断が発生する可能性があります。
  • 一部のクライアント ライブラリには、TLS を有効にする組み込みコントロールが用意されていない場合がありますが、カスタムコードを使用してこの機能をインスタンスに統合できます。