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"
>
サーバー側のトラブルシューティング
サーバー側のトラブルシューティングを次に示します。
サーバー メンテナンス
計画または計画外のメンテナンスによって、クライアント接続が中断される場合があります。 例外の数と種類は、コード パス内の要求の場所と、キャッシュが接続を閉じるタイミングによって異なります。 たとえば、要求を送信するが、フェールオーバーの発生時に応答を受信しない操作では、タイムアウト例外が発生する可能性があります。 接続が閉じられたオブジェクトは、再接続が正常に行われるまで、新しい要求で接続例外を受け取ります。
詳細については、次のセクションを確認してください。
- 更新プログラム チャネルと更新プログラムのスケジュール
- 接続の回復力
AzureRedisEvents
通知
タイムアウトが発生したときに Azure Cache for Redis にフェールオーバーがあったかどうかを確認するには、メトリック エラーを確認します。 Azure portal の [リソース] メニューにある [メトリクス] を選択します。 次に、ErrorType
によって分割された Errors
メトリックを測定する新しいグラフを作成します。 このグラフを作成すると、フェールオーバーの数が表示されます。
フェールオーバーの詳細については、「Azure Cache for Redis のフェールオーバーと修正プログラムの適用」を参照してください。
サーバーの負荷が高い
サーバーの負荷が高い場合、Redis サーバーは要求に対応できないため、タイムアウトになります。 サーバーは応答が遅くなり、要求レートについていけない可能性があります。
サーバーの負荷などのメトリックを監視します。 タイムアウトに対応する Server Load
使用率が急激に増えていないか監視します。 潜在的な影響について早期に通知される、サーバーの負荷などのメトリックに関するアラートを作成します。
高いサーバーの負荷を軽減するために実行できるいくつかの変更を次に示します。
- この記事で指摘されている、深刻なメモリ不足による実行時間の長いコマンドなどの、高いサーバーの負荷の原因を調査します。
- より多くのシャードにスケールアウトして、複数の Redis プロセスに負荷を分散するか、CPU コアを追加してより大きなキャッシュ サイズにスケールアップします。 詳細については、「Azure Cache for Redis 計画に関するよくあるご質問」を参照してください。
- C1 キャッシュの運用ワークロードが一部の内部 Defender のスキャン実行による追加の待機時間によって悪影響を受ける場合は、C2 などの複数の CPU コアを備えた上位レベルのオファリングにスケールすることで、その影響を軽減できます。
サーバー負荷の急増
C0 および C1 キャッシュでは、VM 上で内部 Defender のスキャンが実行されているときに、要求の増加が原因ではないサーバー負荷の短時間のスパイクが 1 日に数回発生することがあります。 これらのレベルで内部 Defender のスキャンが行われている間、要求の待機時間が長くなります。 C0 および C1 レベルのキャッシュには、マルチタスクを実行するコアが 1 つだけあり、内部 Defender のスキャンと 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 - クライアント接続サーバーに関する情報と統計情報を、ほとんど人間が判読できる形式で返します。
ネットワーク帯域幅の制限
キャッシュ サイズが違えば、ネットワーク帯域幅容量も異なります。 サーバーで使用可能な帯域幅を超過すると、データがすぐにはクライアントに送信されません。 サーバーが十分な速さでデータをクライアントにプッシュできないため、クライアント要求はタイムアウトする可能性があります。
"キャッシュの読み取り" および "キャッシュの書き込み" メトリックを使用すると、サーバー側の帯域幅がどれだけ使用されているかを確認できます。 ポータルでこれらのメトリックを表示できます。 潜在的な影響について早期に通知される、キャッシュの読み取りやキャッシュの書き込みなどのメトリックに関するアラートを作成します。
ネットワーク帯域幅の使用量が最大容量に近い状況を緩和するには:
- ネットワーク要求を削減するようにクライアント呼び出し動作を変更します。
- ネットワーク帯域幅容量の多いより大きいキャッシュ サイズにスケーリングします。 詳細については、「Azure Cache for Redis 計画に関するよくあるご質問」を参照してください。
StackExchange.Redis のタイムアウトの例外
StackExchange.Redis を使用する場合のタイムアウトに対処する詳細については、StackExchange.Redis でのタイムアウト例外の調査に関する記事を参照してください。