Azure Cache for Redis の待機時間とタイムアウトに関するトラブルシューティング

タイムリーな応答を受信しないクライアントの操作によって、待機時間が長くなったり、タイムアウト例外が発生したりすることがあります。 操作は、さまざまな段階でタイムアウトする可能性があります。 タイムアウトが発生した場所は、原因と軽減策を特定するのに役立ちます。

このセクションでは、Azure Cache for Redis に接続するときに発生する待機時間とタイムアウトの問題のトラブルシューティングについて説明します。

Note

このガイドのトラブルシューティング手順のいくつかには、Redis コマンドを実行し、さまざまなパフォーマンス メトリックを監視する手順が含まれています。 詳細および手順については、「 追加情報 」セクションの記事を参照してください。

クライアント側のトラブルシューティング

クライアント側のトラブルシューティングを次に示します。

トラフィック バーストとスレッド プールの構成

ThreadPool の設定が適切でないトラフィックのバーストが原因で、Redis Server から既に送信されていてもクライアント側ではまだ使用されていないデータの処理に遅延が発生することがあります。 メトリック "エラー" (種類: UnresponsiveClients) を確認して、クライアント ホストがトラフィックの急増に対応できるかどうかを検証します。

ThreadPoolLogger の例を使用して、ThreadPool 統計が時間の経過と共にどのように変化するかを監視します。 さらに調査するには、StackExchange.Redis からの TimeoutException メッセージを使用できます。

    System.TimeoutException: Timeout performing EVAL, inst: 8, mgr: Inactive, queue: 0, qu: 0, qs: 0, qc: 0, wr: 0, wq: 0, in: 64221, ar: 0,
    IOCP: (Busy=6,Free=999,Min=2,Max=1000), WORKER: (Busy=7,Free=8184,Min=2,Max=8191)

前の例外には、次のような興味深いいくつかの問題が存在します。

  • IOCP セクションと WORKER セクションに、Busy 値が Min 値より大きいことが示されていることに注目してください。 この違いは、ThreadPool 設定に調整が必要なことを示します。
  • in: 64221にも注目してください。 この値は、64,221 バイトがクライアントのカーネル ソケット レイヤーで受信されたが、アプリケーションによって読み取られなかったことを示します。 この違いは、通常、アプリケーション (StackExchange.Redis など) がネットワークからデータを読み取る速度がサーバーのデータ送信速度より遅いことを示します。

バースト シナリオのもとでスレッド プールがすばやくスケールアップするように ThreadPool 設定を構成できます。

大きいキー値

複数のキーと小さい値を使用する方法の詳細については、「そキーを増やすことと値を小さくすることを検討する」を参照してください。

コマンドを使用すると、redis-cli --bigkeys キャッシュ内の大きなキーを確認できます。 詳細については、「redis-cli, the Redis command line interface--Redis」を参照してください。

  • より高い帯域幅機能を使用できるように VM のサイズを増やします。
    • クライアントまたはサーバー VM の帯域幅を増やすと、より大きい応答のデータ転送時間が削減される可能性があります。
    • 両方のコンピューターの現在のネットワーク使用量を現在の VM サイズの制限と比較します。 サーバーのみ、またはクライアントのみの帯域幅を増やすだけでは十分でない可能性があります。
  • アプリケーションが使用する接続オブジェクトの数を増やします。
    • ラウンド ロビン方式を使用して、さまざまな接続オブジェクト経由で要求を発行します。

クライアント ホストの CPU 使用率が高い

クライアントでの高い CPU 使用率は、システムが割り当てられた作業に対応できていないことを示します。 キャッシュがすばやく応答を送信したとしても、クライアントは適切なタイミングでその応答を処理できない可能性があります。 クライアントの CPU を 80% 未満に保つことをお勧めします。 メトリックの "エラー" (種類: UnresponsiveClients) を確認 して、Redis サーバーからの応答をクライアント ホストが時間内に処理できるかどうかを判断します。

Azure Portal で使用可能なメトリックか、またはコンピューター上のパフォーマンス カウンターを使用して、クライアントのシステム全体での CPU 使用率を監視します。 1 つのプロセスの CPU 使用率は低くても、システム全体では高くなる場合があるため、プロセス CPU を監視しないように注意してください。 タイムアウトに対応する CPU 使用率が急激に増えていないか監視します。 CPU が高くなると、[トラフィックのバースト] セクションで説明されているように、TimeoutException エラー メッセージ内の in: XXX 値も高くなる可能性があります。

Note

StackExchange.Redis 1.1.603 以降では、TimeoutException エラー メッセージに local-cpu メトリックが含まれます。 最新バージョンの StackExchange.Redis NuGet パッケージを使用していることを確認します。 バグは、タイムアウトに対する堅牢性を高めるために、コード内で定期的に修正されています。 最新バージョンを用意することが重要です。

クライアントの高い CPU 使用率を緩和するには:

  • CPU スパイクの原因を調査します。
  • クライアントを CPU 容量の多いより大きい VM サイズにアップグレードします。

クライアント ホストのネットワーク帯域幅の制限

クライアント マシンには、そのアーキテクチャに応じて、それぞれ使用できるネットワーク帯域幅に制限がある場合があります。 クライアントがネットワーク容量を過負荷にすることで使用可能な帯域幅を超えている場合、データは、クライアント側でサーバーから送信される速度より速くは処理されません。 この状況により、タイムアウトが発生する場合があります。

BandwidthLogger の例を使用して、帯域幅の使用量が時間の経過と共にどのように変化するかを監視します。 (Azure Web サイトのような) アクセス許可が制限された一部の環境では、このコードが正常に実行されない場合があります。

緩和するには、ネットワーク帯域幅の消費を削減するか、またはクライアント VM サイズをネットワーク容量の多いサイズに増やします。 詳細については、「要求または応答のサイズが大きい」を参照してください。

Linux ベースのクライアント アプリケーションのための TCP の設定

Linux にオプティミスティック TCP の設定があるため、Linux でホストされているクライアント アプリケーションでは接続の問題が発生する可能性があります。 詳細については、「Linux でホストされるクライアント アプリケーションのための TCP の設定」を参照してください。

RedisSessionStateProvider の再試行タイムアウト

RedisSessionStateProvider を使用している場合は、再試行タイムアウトを正しく設定していることを確認してください。 retryTimeoutInMilliseconds の値は、operationTimeoutInMilliseconds の値より大きくする必要があります。 それ以外の場合、再試行は行われません。 次の例では、retryTimeoutInMilliseconds は 3000 に設定されています。 詳細については、「ASP.NET Session State Provider for Azure Cache for Redis 」(Azure Cache for Redis の ASP.NET セッション状態プロバイダー) と「How to use the configuration parameters of Session State Provider and Output Cache Provider」(セッション状態プロバイダーと出力キャッシュ プロバイダーの構成パラメーターの使用方法) を参照してください。

<add 
    name="AFRedisCacheSessionStateProvider"
    type="Microsoft.Web.Redis.RedisSessionStateProvider"
    host="enbwcache.redis.cache.windows.net"
    port="6380"
    accessKey="..."
    ssl="true"
    databaseId="0"
    applicationName="AFRedisCacheSessionState"
    connectionTimeoutInMilliseconds = "5000"
    operationTimeoutInMilliseconds = "1000"
    retryTimeoutInMilliseconds="3000"
>

サーバー側のトラブルシューティング

サーバー側のトラブルシューティングを次に示します。

サーバー メンテナンス

計画または計画外のメンテナンスによって、クライアント接続が中断される場合があります。 例外の数と種類は、コード パス内の要求の場所と、キャッシュが接続を閉じるタイミングによって異なります。 たとえば、要求を送信するが、フェールオーバーの発生時に応答を受信しない操作では、タイムアウト例外が発生する可能性があります。 接続が閉じられたオブジェクトは、再接続が正常に行われるまで、新しい要求で接続例外を受け取ります。

詳細については、次のセクションを確認してください。

タイムアウトが発生したときに Azure Cache for Redis にフェールオーバーがあったかどうかを確認するには、メトリック エラーを確認します。 Azure portal の [リソース] メニューにある [メトリクス] を選択します。 次に、ErrorType によって分割された Errors メトリックを測定する新しいグラフを作成します。 このグラフを作成すると、フェールオーバーの数が表示されます。

フェールオーバーの詳細については、「Azure Cache for Redis のフェールオーバーと修正プログラムの適用」を参照してください。

サーバーの負荷が高い

サーバーの負荷が高い場合、Redis サーバーは要求に対応できないため、タイムアウトになります。 サーバーは応答が遅くなり、要求レートについていけない可能性があります。

サーバーの負荷などのメトリックを監視します。 タイムアウトに対応する Server Load 使用率が急激に増えていないか監視します。 潜在的な影響について早期に通知される、サーバーの負荷などのメトリックに関するアラートを作成します。

高いサーバーの負荷を軽減するために実行できるいくつかの変更を次に示します。

  • この記事で指摘されている、深刻なメモリ不足による実行時間の長いコマンドなどの、高いサーバーの負荷の原因を調査します。
  • より多くのシャードにスケールアウトして、複数の Redis プロセスに負荷を分散するか、CPU コアを追加してより大きなキャッシュ サイズにスケールアップします。 詳細については、「Azure Cache for Redis 計画に関するよくあるご質問」を参照してください。
  • C1 キャッシュの運用ワークロードがウイルス スキャンによる追加の待機時間によって悪影響を受ける場合は、C2 などの複数の CPU コアを備えた上位レベルのオファリングの料金を支払うと、その影響を軽減できます。

サーバー負荷の急増

C0 および C1 キャッシュでは、VM 上でウイルス スキャンが実行されているときに、要求の増加が原因ではないサーバー負荷の短時間の急増が 1 日に数回発生することがあります。 これらのレベルでウイルス スキャンが行われている間、要求の待機時間が長くなります。 C0 および C1 レベルのキャッシュには、マルチタスクを実行するコアが 1 つだけあり、ウイルス スキャンと Redis 要求の処理が分割されます。

メモリ使用量が多い

このセクションは移動しました。 詳細については、「メモリ使用量が多い」を参照してください。

実行時間の長いコマンド

Redis コマンドの中には、他のコマンドより実行コストが高いものがあります。 Redis コマンドのドキュメントは、各コマンドの時間複雑度を示しています。 Redis コマンドの処理はシングル スレッドです。 実行に時間がかかるコマンドでは、その後に続く他のすべてのコマンドがブロックされる可能性があります。

パフォーマンスへの影響を把握するには、Redis サーバーに対して発行しているコマンドを確認してください。 たとえば、KEYS コマンドは多くの場合、それが O(N) 操作であることを認識せずに使用されます。 SCAN を使用して KEYS を回避することにより CPU スパイクを削減できます。

SLOWLOG GET コマンドを実行すると、サーバーに対して実行されているコストの高いコマンドを測定できます。

お客様はコンソールを使用しこれらの Redis コマンドを実行し、実行時間が長い高コスト コマンドを調査できます。

  • SLOWLOG は、Redis の低速クエリ ログの読み取りおよびリセットに使用します。 クライアント側で実行時間の長いコマンドを調査するために使用できます。 Redis Slow Log とは、指定された実行時間を超えたクエリをログに記録するシステムです。 実行時間には、クライアントとの会話、応答の送信などの I/O 操作は含まれません。コマンドを実際に実行するのに必要な時間だけになります。 お客様は、SLOWLOG コマンドを使用して、Redis サーバーに対して実行されてい高コスト コマンドを測定またはログに記録できます。
  • MONITOR は、Redis サーバーによって処理されたすべてのコマンドをストリーム バックするデバッグ コマンドです。 これは、データベースに起こっていることを理解するのに役立ちます。 このコマンドは負荷が高く、パフォーマンスに悪影響を及ぼす可能性があります。 パフォーマンスが低下する可能性があります。
  • INFO - コマンドは、コンピューターによる解析が簡単で、人間が読みやい形式で、サーバーに関する情報と統計情報を返します。 この場合、[CPU] セクションは CPU 使用率を調査するのに役立ちます。 100 (最大値) のサーバー負荷は、Redis サーバーが常にビジー状態であり、要求の処理中にアイドル状態にならなかったことを示します。

出力サンプル:

# CPU
used_cpu_sys:530.70
used_cpu_user:445.09
used_cpu_avg_ms_per_sec:0
server_load:0.01
event_wait:1
event_no_wait:1
event_wait_count:10
event_no_wait_count:1
  • CLIENT LIST - クライアント接続サーバーに関する情報と統計情報を、ほとんど人間が判読できる形式で返します。

ネットワーク帯域幅の制限

キャッシュ サイズが違えば、ネットワーク帯域幅容量も異なります。 サーバーで使用可能な帯域幅を超過すると、データがすぐにはクライアントに送信されません。 サーバーが十分な速さでデータをクライアントにプッシュできないため、クライアント要求はタイムアウトする可能性があります。

"キャッシュの読み取り" および "キャッシュの書き込み" メトリックを使用すると、サーバー側の帯域幅がどれだけ使用されているかを確認できます。 ポータルでこれらのメトリックを表示できます。 潜在的な影響について早期に通知される、キャッシュの読み取りやキャッシュの書き込みなどのメトリックに関するアラートを作成します。

ネットワーク帯域幅の使用量が最大容量に近い状況を緩和するには:

StackExchange.Redis のタイムアウトの例外

StackExchange.Redis を使用する場合のタイムアウトに対処する詳細については、StackExchange.Redis でのタイムアウト例外の調査に関する記事を参照してください。