Redisタイムアウトの発生に関するFAQ


実際のアプリケーションで頻繁にRedisタイムアウトの問題が発生するため、StackExchange RedisはGithub上でTimeoutsの1文を複数の面から分析し、対応する解決策を提供します.
実際のアプリケーションで頻繁にRedisタイムアウトの問題が発生するため、StackExchange.RedisはGithubでTimeoutsという文章を複数の面から分析し、対応する解決策を提供し、後日再びこの問題が発生したときに迅速に調べることができるように、本文を技術ノートとして書き、同時に英語があまりよくないプログラマー(媛)に参考を提供する.
余談ですが、今日はプログラマー(媛)の日で、同行の祝日の楽しみ、体の健康、徹夜から離れることを祈っています.
 
StackExchangeを使用する場合.Redisのプログラマー(媛)は、以下のような異常によく遭遇します.
Timeout performing GET keyName, inst: 1, mgr: ExecuteSelect, err: never, queue: 2, qu: 2, qs: 0, qc: 0, wr: 0, wq: 0, in: 0, ar: 0, clientName: computerName, IOCP: (Busy=0,Free=1000,Min=4,Max=1000), WORKER: (Busy=4,Free=32763,Min=4,Max=32767), Local-CPU: unavailable (Please take a look at this article for some common client-side issues that can cause timeouts: https://github.com/StackExchange/StackExchange.Redis/tree/master/Docs/Timeouts.md)
すなわち、Redis実行タイムアウトは、以下のような問題がある可能性があります.

1.ネットワーク、CPUまたはメモリ(RAM)によって制限されていますか。


クライアントとRedis-Serverを構築するサーバがサポートする最大帯域幅を確認します.一部のリクエスト(request)が帯域幅に制限されている場合、タイムアウトを引き起こす可能性があります.同様に、クライアントまたはサーバ上のCPUによって制限されているかどうかを確認します.これにより、要求待ちCPU時間がタイムアウトします.また、Redisデータ量が割り当てられたメモリ(RAM)の制限を超えると、Redisロックが発生し、タイムアウトを招く場合も無視されやすい.

2、コマンド(command)がRedisサーバ上で処理された場合、長い時間がかかりますか?


Redisサーバで処理するのに時間がかかるコマンドがあり、リクエストがタイムアウトする場合があります.長時間コマンドを実行する例には、mgetの大量のキー、keys*、またはうまく書けないluaスクリプトがあります.SlowLogコマンドを実行して、要求が予想よりも長くかかったかどうかを確認できます.コマンドの詳細については、ここを参照してください.

3、Redisへのいくつかの小さなリクエストの前に大量のリクエストがタイムアウトしましたか?


エラーメッセージのパラメータ「qs」は、クライアントからサーバに送信されたリクエストの数を示しますが、まだ応答していません.いくつかのタイプのロードでは、StackExchangeのため、この値(qs)が増加していることがわかります.Redisは単一のTCP接続を使用し,一度に1つの応答しか読み取れない.最初のオペレーションがタイムアウトしても、サーバへのデータの送信を停止(または)することはなく、他のリクエストも完了するまでブロックされ、タイムアウトを招きます.1つの解決策は、redis-serverがワークロードの十分なキャッシュを満たし、大きな値をより小さなブロックに分割することによって、タイムアウトの機会を最小限に抑えることです.もう1つの可能な解決策は、クライアントでConnectionMultiplexerオブジェクトプールを使用し、新しいリクエストを送信するときに「最小ロード」ConnectionMultiplexerを選択することです.これにより、単一のタイムアウトによる他のリクエストのタイムアウトが防止されます.

4、タイムアウト異常で、多忙または多忙な作業スレッドが大量に見られますか?


スレッド・プールの成長の詳細について説明します.
CLRスレッドプールには、「ワークスレッド」と「I/O完了ポート」(I/O Completion Port、別名IOCP)の2種類のスレッドがあります.
  • の動作スレッドは、Taskと同様の処理に用いる.Run(・・)またはThreadPool.QueUserWorkItem(…)メソッドのもの.作業がバックグラウンドスレッド上で行われる必要がある場合、これらのスレッドもCLR内の様々なコンポーネントによって使用される.
  • 非同期IOが発生した場合(例えば、ネットワークから読み出される)、IOCPスレッドが使用される.

  • スレッドプールは、必要に応じて(調整なし)新しいワークスレッドまたはI/O完了スレッドを提供し、各スレッドタイプの「最小値」設定に達するまで実行します.デフォルトでは、最小スレッド数はシステム上のプロセッサ数に設定されています.
    既存の(ビジー)スレッドの数が「最小」スレッド数に達すると、スレッドプール(ThreadPool)は、500ミリ秒ごとに1つのスレッドに新しいスレッドを注入する速度を調整します.これは、システムがIOCPスレッドのワークバースト(burst of work)を必要とする場合、この作業をすぐに処理することを意味します.ただし、ワークバーストが構成の「最小」設定を超えると、スレッドプールが2つの状況が発生するのを待つため、いくつかの作業を処理する際に遅延が発生します.1、既存のスレッドは自由に作業を処理できます.2、既存のスレッドは500 ms空きがないので、新しいスレッドを作成します.
    基本的には、ビジースレッドの数が最小スレッドより大きい場合、アプリケーションがネットワークトラフィックを処理する前に500 msの遅延を消費する可能性があります.さらに、既存のスレッドが15秒以上空いている場合(私が覚えている)は、この成長と収縮の周期を繰り返すことができるようにクリーンアップされることに注意してください.
    もし私たちがStackExchangeを見たらRedis(build 1.0.450以降)のエラーメッセージには、現在のスレッドプールの統計が表示されます(次のIOCPおよびWORKERの詳細を参照).
    System.TimeoutException: Timeout performing GET MyKey, inst: 2, mgr: Inactive,
    queue: 6, qu: 0, qs: 6, qc: 0, wr: 0, wq: 0, in: 0, ar: 0,
    IOCP: (Busy=6,Free=994,Min=4,Max=1000),
    WORKER: (Busy=3,Free=997,Min=4,Max=1000)
    上記の例では、IOCPスレッドに対して6つのビジースレッドがあり、システムは4つの最小スレッド数を許可するように構成されていることがわかります.この場合、クライアントは6>4のため、500ミリ秒の遅延を2つ見ることができる.
    IOCPまたはWORKERスレッドの成長が制限されている場合、StackExchangeに注意してください.Redisはタイムアウトにヒットします.
    推奨事項:上記の情報を考慮して、IOCPおよびWORKERスレッドの最小構成値をデフォルト値より大きい値に設定することを推奨します.1つのアプリケーションの適切な値が他のアプリケーションに対して高すぎるか低すぎるため、この値がどれだけあるべきかを一刀で指導することはできません.この設定は複雑なアプリケーションの他のパフォーマンスにも影響します.そのため、特定のニーズに応じて設定を調整する必要があります.好ましい初期値は200または300であり、必要に応じてテストおよび調整される.
    この設定を設定する方法:
  • はASP.NETでは、「minIoThreads」構成を使用して、machineを設定.configファイルの構成要素.Azure WebSitesの内部で実行している場合、この設定はコンフィギュレーションオプションでは表示されません.global.asax.csでのApplication_Startメソッドはプログラミングで設定されます(以下を参照).

  • 重要:この構成要素で指定した値は、各コアで設定されています.たとえば、4コアのマシンを持っていて、minIthreadsの実行時に200に設定したい場合は、を使用して設定します.
  • はASP.NET以外はThreadPoolを使用する.SetMinThreads(……) API.

  • 原文住所:https://github.com/StackExchange/StackExchange.Redis/tree/master/Docs/Timeouts.md