Memorystore for Redis は、スループット、CPU 使用率、メモリ使用量をモニタリングするためのリアルタイムのサーバーサイド指標を提供しますが、このデータだけでは、複雑な分散システム内でクライアント アプリケーションのレイテンシが高くなる理由を説明できない場合があります。
クライアントサイドの指標は、リクエストとレスポンスのサイクル全体を可視化することで、この問題を解決します。アプリケーションがコマンドを開始してから、アプリケーションがレスポンスを処理するまでの時間を測定します。これらのデータポイントをキャプチャすることで、レイテンシがアプリケーション ロジック、ネットワーク パス、Redis サーバーのいずれに起因するかを正確に判断できます。
始める前に
クライアント アプリケーションがサービス アカウントを使用し、次の Identity and Access Management(IAM)ロールが割り当てられていることを確認します。
roles/cloudtrace.agent(Cloud Trace エージェント)roles/monitoring.metricWriter(モニタリング指標の書き込み)
ロール付与の詳細については、コンソールを使用して IAM ロールを付与する Google Cloud クイックスタートをご覧ください。
Cloud Monitoring API を有効にする
クライアントサイドの指標を Monitoring にエクスポートするには、 アプリケーションで Monitoring API を有効にする必要があります。 これらの指標を Monitoring でエクスポートして可視化することで、ボトルネックの根本原因を特定し、レイテンシの発生源を特定できます。
Monitoring API を有効にするには、次の操作を行います。
コンソール Google Cloud で、[API とサービス] ページに移動します。
Memorystore for Redis インスタンスを作成したプロジェクトを選択します。
[API とサービスを有効化] をクリックします。
monitoringを検索します。検索結果で、[Cloud Monitoring API] をクリックします。
[API が有効です] が表示されている場合、API はすでに有効になっています。表示されていない場合は、[有効にする] をクリックします。
Cloud Trace API を有効にする
Trace で分散トレースを表示するには、Trace API を 有効にする必要があります。Trace エクスプローラを使用してこれらのトレースを表示し、ボトルネックを診断して、アプリケーションのレイテンシの原因を特定できます。
Trace API を有効にするには、次の操作を行います。
コンソール Google Cloud で、[API とサービス] ページに移動します。
Memorystore for Redis インスタンスを作成したプロジェクトを選択します。
[API とサービスを有効化] をクリックします。
traceを検索します。検索結果で、[Cloud Trace API] をクリックします。
[API が有効です] が表示されている場合、API はすでに有効になっています。表示されていない場合は、[有効にする] をクリックします。
クライアントサイドの指標を有効にする
クライアントサイドの指標を有効にするには、OpenTelemetry SDK、Cloud Monitoring エクスポータ、Cloud Trace エクスポータをアプリケーションのコードに追加します。OpenTelemetry 計測は、アプリケーションの Redis クライアント ライブラリ内で直接実行され、指標をキャプチャします。これにより、アプリケーションはレイテンシ データポイントを記録し、可視化のために Monitoring と Trace にエクスポートできます。
クライアントサイドの指標を有効にするには、Go、 Java、Node.js、 または Python を使用できます。各言語の指標を有効にする方法については、次のタブをご覧ください。
Go
必要な OpenTelemetry と Google Cloud エクスポータ の依存関係をインストールするには、ターミナルで次のコマンドを実行します。
go get github.com/gomodule/redigo/redis@latest go get go.opentelemetry.io/otel go get go.opentelemetry.io/otel/sdk/trace go get go.opentelemetry.io/otel/sdk/metric go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace go get github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric
クライアントサイドの指標を有効にするには、
main.goファイルを作成し、次のコードを追加します。エクスポータが公開された指標をバッチ処理して Monitoring に送信するのに十分な時間を確保するため、アプリケーションを 1 分以上実行します。
Java
必要な OpenTelemetry と Google Cloud エクスポータ の依存関係をインストールするには、アプリケーションの
pom.xmlファイルに次のコードを追加します。クライアントサイドの指標を有効にするには、
RedisTelemetryApp.javaファイルを作成し、次のコードを追加します。エクスポータが公開された指標をバッチ処理して Monitoring に送信するのに十分な時間を確保するため、アプリケーションを 1 分以上実行します。
Node.js
必要な OpenTelemetry と Google Cloud エクスポータ の依存関係をインストールするには、ターミナルで次のコマンドを実行します。
npm install redis@^4.6.0 @opentelemetry/api@^1.9.0 @opentelemetry/sdk-trace-node@^2.1.0 @opentelemetry/sdk-trace-base@^2.1.0 @opentelemetry/sdk-metrics@^2.1.0 @opentelemetry/instrumentation@^0.205.0 @opentelemetry/instrumentation-redis@^0.67.0 @google-cloud/opentelemetry-cloud-trace-exporter@^3.0.0 @google-cloud/opentelemetry-cloud-monitoring-exporter@^0.21.0 @opentelemetry/resources@^2.1.0
クライアントサイドの指標を有効にするには、
server.jsファイルを作成し、次のコードを追加します。エクスポータが公開された指標をバッチ処理して Monitoring に送信するのに十分な時間を確保するため、アプリケーションを 1 分以上実行します。
Python
必要な OpenTelemetry と Google Cloud エクスポータ の依存関係をインストールするには、ターミナルで次のコマンドを実行します。
pip install redis==7.0.1 opentelemetry-api==1.39.1 opentelemetry-sdk==1.39.1 opentelemetry-instrumentation-redis==0.60b1 opentelemetry-exporter-gcp-trace==1.11.0 opentelemetry-exporter-gcp-monitoring==1.11.0a0
クライアントサイドの指標を有効にするには、
main.pyファイルを作成し、次のコードをアプリケーションに追加します。エクスポータが公開された指標をバッチ処理して Monitoring に送信するのに十分な時間を確保するため、アプリケーションを 1 分以上実行します。
Monitoring で指標を表示する
クライアントサイドの指標を有効にし、エクスポータが指標をバッチ処理して Monitoring に送信するのに十分な時間を確保するため、アプリケーションを 1 分以上実行したら、Monitoring を使用して指標を可視化し、オペレーションまたはインスタンスごとにグループ化して、アグリゲータを適用してアプリケーションのパフォーマンスをモニタリングします。
Monitoring で指標を表示するには、次の操作を行います。
コンソール Google Cloud で、Metrics Explorer のページに移動します。
プロジェクト Google Cloud を選択します。
[指標を選択] をクリックします。
workload.googleapis.com/redisを検索します。クライアントサイドの指標を選択します。必要に応じて、データを
operationとinstanceでグループ化し、アグリゲータを選択します。その他のオプションについては、Metrics Explorer を使用して指標を選択するをご覧ください。
Trace で分散トレースを表示する
アプリケーションがデータのエクスポートを開始したら、Trace を使用して Redis コマンドのリクエストとレスポンスのサイクル全体を可視化できます。Trace で分散トレースを表示すると、ボトルネックを診断して、アプリケーションのレイテンシの正確な原因を特定できます。
Trace で分散トレースを表示するには、次の操作を行います。
Google Cloud コンソールで、[**Trace エクスプローラ**] ページに移動します。
散布図の点で表される最近のトレースを選択します。
ウォーターフォール ビューを調べて、次のボトルネックを特定することで、レイテンシの原因を特定します。
リクエストの合計時間: 最上位(親)のバーは、オペレーションが完了するまで待機する必要がある合計 時間を示します。
ネットワークとサーバーのレイテンシ(RTT): 子バー(
GETやSETなどのラベルが付いたバー)は、コマンドがネットワークを介して移動し Memorystore for Redis サーバーで実行されるまでの時間を示します。クライアント接続のブロック: Redis 子スパンが開始する前に大きな空白の水平方向のギャップがある場合、アプリケーション スレッドは接続プールから使用可能な TCP 接続を待機しています。
アプリケーションの解析のブロック: Redis 子スパンが終了した後に大きな空白の水平方向のギャップ がある場合、アプリケーションは返されたペイロードの解析 または処理に苦労しています。これは、数メガバイトの JSON 文字列でよく発生します。
再試行: 同じ親トレース内で同じコマンドの短い子スパンが複数連続して表示される場合、クライアントでネットワーク パケットロスが発生し、指数バックオフ再試行ループをトリガーする必要があります。
トラブルシューティング
このセクションでは、クライアントサイドの指標を使用して特定できる一般的なパフォーマンスの問題、その根本原因、問題のトラブルシューティングに関するガイダンスについて説明します。
| 問題 | 原因 | トラブルシューティング |
|---|---|---|
アプリケーションでレイテンシが急増しますが、 Memorystore for Redis は完全に正常に見えます。
|
ボトルネックはアプリケーション内にあります。スレッドは Redis コマンドを実行しようとしますが、接続プールが完全に使い果たされています。redis_client_blocking_latency が高い場合は、
コマンドがネットワークに送信される前に、使用可能な TCP ソケットを待機するコードの時間を表します。 |
同時トラフィックの増加に対応するには、Redis クライアント構成で接続プールサイズの制限を増やします(Go の場合は MaxActive、Java の場合は MaxTotal、Node.js と Python の場合は max_connections)。 |
リクエストは完了しますが、エンドポイントの処理に想定よりも時間がかかります 。ネットワークまたはサーバーの健全性に関連する問題はありません。
|
Memorystore for Redis はコマンドを実行し、ネットワークは
ペイロードを迅速に転送します(RTT が低い)。ただし、返されるペイロードは大きくなります(たとえば、15 MB の JSON 文字列)。アプリケーションがメモリを割り当てて、その
大きな文字列をオブジェクトに逆シリアル化する際に過剰なリソースを消費するため、アプリケーションの
redis_application_blocking_latencyが高くなります。 |
データモデルを最適化します。単一のキーに大量の JSON BLOB を保存しないでください。
Redis ハッシュ(HSET)を使用してデータを分割し、
HGET または HMGET を使用して必要な特定のフィールド
のみを取得します。
|
ユーザー向けアプリケーションのレイテンシが急増しますが、Redis 指標 ではサーバーのレイテンシが低く、接続プールのチェックアウトが通常どおりです。
|
redis_client_rtt は成功したリクエストの RTT のみをキャプチャするため、失敗したパケットのタイムアウト時間は反映されません。アプリケーションで一時的なパケット ドロップまたは TCP
リセットが発生すると、インストルメント化されたクライアントの再試行ロジックにより
redis_retry_count が増加し、指数バックオフ ループがトリガーされます。
これにより、試行間にスリープ時間が導入されます(たとえば、
100ms、200ms、400ms)。ユーザーは
合計レイテンシが高くなりますが、根本原因はネットワーク
パケットロスであり、クライアントサイドのスリープ遅延がトリガーされます。 |
VPC フローログで、パケットのドロップ、帯域幅の調整、
リージョン間のルーティングの異常を確認します。タイムアウトが頻繁に発生する場合は、一時的なネットワーク ジッターを考慮して、クライアント接続のタイムアウト(socket_timeout または
connect_timeout)が想定される RTT より大きいことを確認してください。 |
すべてが停止し、テレメトリー パイプラインのすべてのレイヤで レイテンシが高くなります。
|
Redis はシングルスレッドです。O(N)
時間計算量コマンド (大規模なセットに対する KEYS *、数百万の
フィールドを含むハッシュに対する SMEMBERS
、または HGETALL) を実行すると、Redis エンジンはそのリクエストを満たすために一時停止します。そのコマンド
が実行されている間、他のすべてのアプリケーション リクエストがキューに登録され、システム全体のレイテンシ
が急増します。カスタム redis_client_rtt がサーバーのレイテンシ(commands/usec_per_call)と一致するため、コマンドを実行するサーバーがボトルネックになります。 |
Trace を開き、遅い スパンの Redis コマンドを確認して、ブロックの原因となっているクエリを特定します。コードで、ブロッキング コマンド をノンブロッキング コマンドに置き換えます。 サーバー スレッドをロックせずに大規模なデータセットを段階的に反復処理するには、 |
トラフィックが少ない場合でも、アプリケーションは すべての Redis コマンドで一貫して高いベースライン レイテンシを報告します。
|
Redis サーバーはコマンドを即座に実行しますが、アプリケーションとインスタンスは異なるリージョン(たとえば、us-central1 と us-east1)にデプロイされます。すべてのネットワーク パケットは、これらの地理的なデータセンター間の物理的な Google Cloud インフラストラクチャを通過する必要があります。これにより、往復ごとに、光速のリージョン間レイテンシ ペナルティが強制的に発生します。 |
レイテンシを短縮するには、インスタンスと同じリージョン とゾーンにアプリケーションをデプロイします。アプリケーションとインスタンスのリージョンを表示するには、 Google Cloud コンソールを使用します。 |
次のステップ
- クライアントサイドの指標の詳細を確認する。
- Memorystore for Redis で使用できるクライアントサイドの指標について学習する。