次の方法で共有


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

タイムリーな応答を受け取らない Azure Cache for Redis クライアント操作では、待機時間が長くなるか、タイムアウト例外が発生する可能性があります。 この記事では、待機時間とタイムアウトが長くなる可能性がある一般的な問題をトラブルシューティングする方法について説明します。

操作では、さまざまな段階で問題が発生したりタイムアウトしたりする可能性があります。 問題の原因は、原因と軽減策の特定に役立ちます。 この記事は、クライアント側とサーバー側の問題に分かれています。

クライアント側の問題

サーバー側の問題

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

次のクライアント側の問題は、待機時間とパフォーマンスに影響し、タイムアウトにつながる可能性があります。

クライアント接続数の増大

キャッシュの最大値を超えるクライアント接続に対するクライアント要求が失敗する可能性があります。 また、クライアント接続が多いと、再接続試行の繰り返しを処理するときに、サーバーの負荷が高くなる場合もあります。

クライアント接続が多い場合は、クライアント コードでの接続リークを示している可能性があります。 接続が再利用されていなかったり、適切に閉じられていなかったりすることがあります。 クライアント コードの接続の使用法を見直してください。

高い接続がすべて正当で必要なクライアント接続である場合は、接続制限が高いサイズにキャッシュをアップグレードすることが必要になる場合があります。 接続済みクライアントの最大集計メトリックが、キャッシュ サイズで許可されている接続の最大数に近いか、それより大きいかどうかを確認します。 クライアント接続ごとのサイズ設定の詳細については、「Azure Cache for Redis のパフォーマンス」をご覧ください。

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

クライアントの CPU 使用率が高い場合は、システムが割り当てられた作業に対応できないことを示します。 キャッシュが応答を迅速に送信した場合でも、クライアントは応答を十分に高速に処理できない可能性があります。 クライアントの CPU を 80%未満に保つのが最善です。

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

  • CPU スパイクの原因を調査します。
  • より多くの CPU 容量を持つより大きな仮想マシン (VM) サイズにクライアントをアップグレードします。

Azure portal で使用できるメトリックまたは VM のパフォーマンス カウンターを使用して、クライアントのシステム全体の CPU 使用率を監視します。 メトリック エラー (種類: UnresponsiveClients) を調べて、クライアント ホストが Redis サーバーからの応答を時間内に処理できるかどうかを判断します。

1 つのプロセスで CPU 使用率が低くなる可能性がありますが、システム全体の CPU が高くなる可能性があるため、プロセス CPU を監視しないように注意してください。 タイムアウトに対応する CPU 使用率が急激に増えていないか監視します。 CPU が高い場合は、timeoutExceptionエラー メッセージで高いin: XXX値が発生する可能性もあります。 例については、 トラフィック バーストとスレッド プールの構成 に関するセクションを参照してください。

StackExchange.Redis 1.1.603 以降では、local-cpu エラー メッセージに timeoutException メトリックが含まれます。 コードのタイムアウトに対する耐性を高めるためにバグが定期的に修正されるため、 StackExchange.Redis NuGet パッケージの最新バージョンを使用してください。 詳細については、「 StackExchange.Redis での timeout 例外の調査」を参照してください。

大きいキー値

コマンドを使用すると、redis-cli --bigkeys キャッシュ内の大きなキーを確認できます。 Redis コマンド ライン インターフェイスである redis-cli の詳細については、 Redis CLI を参照してください。

問題を軽減するには:

  • より高い帯域幅機能を得るために、VM のサイズを増やします。 クライアントまたはサーバー VM の帯域幅を増やすと、より大きい応答のデータ転送時間が削減される可能性があります。 両方の VM での現在のネットワーク使用量を、現在の VM サイズの制限と比較します。 サーバーまたはクライアントのみの帯域幅が増えるだけでは不十分な場合があります。

  • アプリケーションが使用する接続オブジェクトの数を増やします。 ラウンド ロビン方式を使用して、異なる接続オブジェクト経由で要求を送信します。 複数のキーと小さい値を使用する方法の詳細については、「そキーを増やすことと値を小さくすることを検討する」を参照してください。

Redis クライアントでのメモリ不足

クライアントのメモリ不足により、キャッシュ応答の処理が遅れるパフォーマンスの問題が発生する可能性があります。 メモリ不足が発生すると、システムはデータをディスクにページングする可能性があります。 この ページ フォールト により、システムの処理速度が大幅に低下します。

クライアントでのメモリ不足を検出するには:

  • VM のメモリ使用量を監視して、使用可能なメモリを超えないようにします。
  • クライアントの Page Faults/Sec パフォーマンス カウンターを監視します。 通常の動作中、ほとんどのシステムでいくつかのページ フォールトが発生します。 要求タイムアウトに対応するページ フォールトのスパイクは、メモリ不足を示している場合があります。

クライアントの高いメモリ負荷を軽減するには:

  • メモリ使用量パターンを調査して、クライアントのメモリ消費量を減らします。
  • クライアント VM をメモリ量の多いより大きいサイズにアップグレードします。

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

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

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

RedisSessionStateProvider retryTimeout

RedisSessionStateProviderを使用する場合は、retryTimeoutを正しく設定してください。 retryTimeoutInMilliseconds の値は、operationTimeoutInMilliseconds の値より大きくする必要があります。 それ以外の場合、再試行は行われません。

次の例では、retryTimeoutInMilliseconds3000 に設定されています。

<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"
>

詳細については、以下を参照してください。

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

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

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

ThreadPool の設定が適切でないトラフィックのバーストが原因で、Redis Server から既に送信されていてもクライアント側ではまだ使用されていないデータの処理に遅延が発生することがあります。 エラー (種類: UnresponsiveClients) メトリックを調べて、クライアント ホストがトラフィックの急激な急増に対応できるかどうかを検証します。 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 など) が、サーバーから送信されるほど迅速にネットワークからデータを読み取らないことを意味します。

StackExchange.Redis 1.1.603 以降では、local-cpu エラー メッセージに timeoutException メトリックが含まれます。 コードのタイムアウトに対する耐性を高めるためにバグが定期的に修正されるため、 StackExchange.Redis NuGet パッケージの最新バージョンを使用してください。 詳細については、「 StackExchange.Redis でのタイムアウト例外の調査」を参照してください。

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

次のサーバー側の問題は、パフォーマンスに影響し、タイムアウトにつながる可能性があります。

メモリ使用量が多い

サーバーのメモリ不足により、要求処理を遅らせるさまざまなパフォーマンスの問題が発生する可能性があります。 メモリ不足が発生すると、システムはデータをディスクにページし、システムの速度が大幅に低下します。

メモリ不足の原因としては、キャッシュの最大容量に近いデータがキャッシュに格納されていること、または Redis サーバーのメモリ断片化が高いなどの原因が考えられます。

断片化は、たとえばデータが 1 KB と 1 MB のサイズに分散されている場合など、サイズの変動が大きいデータを読み込みパターンが格納している場合に発生する可能性があります。 1 KB のキーが既存のメモリから削除されると、1 MB のキーが領域に収まらないので、断片化が発生します。 同様に、1 MB のキーが削除された場合、追加された 1.5 MB のキーは、既存の再利用されたメモリに収まりません。 この未使用の空きメモリにより、断片化が発生します。

キャッシュが断片化され、メモリ不足で実行されている場合、システムはフェールオーバーを実行して常駐セット サイズ (RSS) メモリの回復を試みます。 Redis では、INFO コマンドを使用して、used_memoryused_memory_rssの 2 つの統計情報が公開されます。これは、この問題を特定するのに役立ちます。 これらのメトリックは、Azure portal で表示することもできます。

used_memory_rss 値が used_memory メトリックの 1.5 倍より大きい場合、メモリに断片化があります。 断片化が原因で問題が生じるのは次のようなときです。

  • メモリ使用量がキャッシュの最大メモリ制限に近い。
  • used_memory_rss メトリックが最大メモリ制限を超えているため、ページがメモリにエラーが発生する可能性があります。

メモリ使用量を正常に保つために、いくつかのアクションを実行できます。

メモリ管理に関するその他の推奨事項については、「 メモリ管理のベスト プラクティス」を参照してください。

サーバーの負荷が高い

サーバーの負荷が高いということは、Redis サーバーがビジー状態であり、要求に対応できず、タイムアウトや応答速度が低下することを意味します。 高いサーバー負荷を軽減するには、まず、メモリ負荷が高いために 実行時間の長いコマンド などの原因を調査します。

Azure portal からサーバーの負荷などの メトリックを監視 できます。 サーバー負荷メトリックを確認するには、キャッシュ ページの左側のナビゲーション メニューから [監視] の下にある [分析情報] を選択し、サーバーの負荷グラフを表示します。 または、左側のナビゲーション メニューの [監視] で [メトリック] を選択し、[メトリック][サーバーの負荷] を選択します。

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

サーバー負荷の急増

C0 および C1 キャッシュでは、VM 上で内部 Defender スキャンが実行されている間、要求の増加によって引き起こされないサーバー負荷のスパイクが短時間発生することがあります。 これらのレベルでは、内部 Defender スキャンの実行中に要求の待機時間が長くなります。

C0 および C1 レベルのキャッシュには、マルチタスクに対するコアが 1 つだけあり、内部 Defender スキャンと Redis 要求の処理を分割します。 内部 Defender スキャンによる余分な待機時間が C1 キャッシュ上の運用ワークロードに悪影響を与える場合は、C2 などの複数の CPU コアを備えた上位レベルのオファリングにスケーリングできます。 詳細については、「 適切なレベルの選択」を参照してください。

クライアント接続数の急激な変更の詳細については、「 クライアント接続の急増を回避する」を参照してください。

Scaling

より多くのシャードに スケールアウト して、複数の Redis プロセスに負荷を分散したり、CPU コア数を増やしてより大きなキャッシュ サイズにスケールアップしたりできます。 スケーリング操作は、ノード間でのデータの移動やクラスター トポロジの変更を伴う可能性があるため、CPU とメモリを集中的に使用します。 詳細については、 Azure Cache for Redis の計画に関する FAQスケーリングに関するページを参照してください。

実行時間の長いコマンド

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

Redis サーバーに発行するコマンドを確認して、パフォーマンスへの影響を理解します。 たとえば、 KEYS コマンドは、大きな O 表記 (O(N)) 操作であることを知らなくてもよく使用されます。 CPU スパイクを減らすために、SCAN を使用してKEYSを回避できます。

コンソールで次の Redis コマンドを実行して、実行時間の長いコマンドとコストの高いコマンドを調査できます。

  • CLIENT LIST

    CLIENT LIST コマンドは、クライアント接続サーバーに関する情報と統計情報を、ほとんど人間が判読できる形式で返します。

  • INFO

    INFO コマンドは、コンピューターが解析しやすく、人間が読みやすい形式でサーバーに関する情報と統計情報を返します。 CPUセクションは、CPU 使用率を調査するのに役立ちます。 100 (最大値) のserver_loadは、Redis サーバーが常にビジー状態であり、要求の処理中にアイドル状態にならなかったことを示します。

    次の例は、 INFO コマンドからの出力を示しています。

    # 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
    
  • モニター

    MONITOR は、Redis サーバーによって処理されるすべてのコマンドをストリーム バックするデバッグ コマンドです。 MONITOR は、データベースに何が起こっているかを理解するのに役立ちます。 このコマンドは要求が厳しく、パフォーマンスに悪影響を与え、低下する可能性があります。

  • SLOWLOG

    Redis Slow Log とは、指定された実行時間を超えたクエリをログに記録するシステムです。 実行時間には、クライアントとの通信や応答の送信などの I/O 操作は含まれませんが、コマンドを実際に実行するために必要な時間のみが含まれます。

    SLOWLOG コマンドは、Redis 低速クエリ ログの読み取りとリセットを行います。また、クライアント側で実行時間の長いコマンドを調査するためにも使用できます。 SLOWLOG GET を使用すると、Redis サーバーに対して実行されているコストの高いコマンドを監視およびログに記録できます。

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

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

Azure portal でキャッシュの読み取りとキャッシュ書き込みなどのメトリックを監視して、使用されているサーバー側の帯域幅の量を確認できます。 潜在的な影響について早期に通知されるように、これらのメトリックに関するアラートを作成します。

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

サーバー メンテナンス

計画または計画外のメンテナンスによって、クライアント接続が中断される場合があります。 例外の数と種類は、コード パス内の要求の場所と、キャッシュが接続を閉じるタイミングによって異なります。

Azure Redis Cache でフェールオーバーが発生した場合、ダウンしたノードからのクライアント接続はすべて、まだ実行中のノードに転送されます。 接続が増加したため、サーバーの負荷が急増する可能性があります。 クライアント アプリケーションの再起動を試みて、すべてのクライアント接続が再作成されて 2 つのノード間で再配布されるようにすることができます。

要求を送信するが、フェールオーバーが発生したときに応答を受け取らない操作では、 timeout 例外が発生する可能性があります。 接続が閉じられたオブジェクトは、再接続が正常に行われるまで、新しい要求で接続例外を受け取ります。

timeout例外が発生した期間中に Azure Redis Cache にフェールオーバーが発生したかどうかを確認するには、Errors メトリックを確認します。 キャッシュの Azure portal ページで、左側のナビゲーション メニューの [監視] の下にある [メトリック] を選択します。 次に、 ErrorType で分割されたエラー メトリックを測定する新しいグラフ を作成します。 このグラフを作成すると、フェールオーバーの数が表示されます。 フェールオーバーの詳細については、「Azure Cache for Redis のフェールオーバーと修正プログラムの適用」を参照してください。

サーバーのメンテナンスによる問題の軽減の詳細については、次の記事を参照してください。