次の方法で共有


Azure Managed Redis 管理に関する FAQ

この記事では、Azure Managed Redis の管理に役立つ、よくある質問に対する回答について説明します。

Redis への接続に非 TLS/SSL ポートを有効にする必要がある状況

事実上すべての Redis のユース ケースで TLS を使用することをお勧めします。 TLS なしで接続するオプションは、下位互換性のために含まれています。

いくつかの運用上のベスト プラクティスについて

StackExchange.Redis のベスト プラクティス

  • AbortConnect を "false" に設定してから、ConnectionMultiplexer による自動再接続を待ってください。
  • 要求ごとに新しい接続を作成するのではなく、有効期間が長い 1 つの ConnectionMultiplexer インスタンスを使用します。
  • 値が小さいほど Redis のパフォーマンスは向上するため、大きなデータは複数のキーに分割することを検討してください。 この Redis に関する議論では、100 KB は大きいと見なされています。 詳しくは、開発のベスト プラクティスに関するセクションをご覧ください。
  • タイムアウトを回避するために ThreadPool 設定 を構成します。
  • connectTimeout については既定の 5 秒以上を使用してください。 この間隔により、ネットワーク ブリップが発生した場合に接続を再確立するための十分な時間が StackExchange.Redis に与えられます。
  • 実行中のさまざまな操作に関連するパフォーマンス コストを把握してください。 たとえば、 KEYS コマンドは O(n) 操作であるため、使用しないでください。 redis.io のサイト に、Redis でサポートされる各操作の時間計算量の詳細が記載されています。 各コマンドを選択して、操作ごとの時間計算量を確認してください。

構成と概念

パフォーマンス テスト

一般的な Redis コマンドの使用に関するいくつかの考慮事項

  • 完了するのに時間がかかる特定の Redis コマンドについては、その結果を完全に理解しないまま使用するのは避けてください。 たとえば、運用環境では KEYS コマンドを実行しないでください。 キーの数によっては、復帰に時間がかかる可能性があります。 各 Redis のシャードはシングル スレッドであり、一度に 1 つずつコマンドを処理します。 KEYS の後で他のコマンドを発行した場合、それらのコマンドは Redis によって KEYS コマンドが処理されるまで処理されません。 redis.io のサイト に、Redis でサポートされる各操作の時間計算量の詳細が記載されています。 各コマンドを選択して、操作ごとの時間計算量を確認してください。
  • キー サイズ - 小さなキー/値と大きなキー/値のどちらを使用するか。 これはシナリオによって異なります。 ご利用のシナリオで、より大きなキーが必要な場合は、ConnectionTimeout を調整してから、値を再度試して再試行ロジックを調整することができます。 Redis サーバーの観点からは、値が小さいほど、パフォーマンスは向上します。
  • これらの考慮事項は、サイズの大きな値を Redis に格納できないという意味ではありません。次の点を考慮する必要があります。 待機時間が長くなります。 サイズの大きなデータ セットとサイズの小さなデータ セットがある場合は、複数の ConnectionMultiplexer インスタンスを使用できます。 前の「StackExchange.Redis 構成オプションの実行」セクションで説明したように、タイムアウト値と再試行値の異なるセットを使用してそれぞれを構成します。

キャッシュのベンチマークを実行およびテストする方法

ThreadPool 拡大の重要な詳細情報

CLR ThreadPool には、 ワーカー スレッドと I/O 完了ポート (IOCP) スレッドの 2 種類のスレッドがあります。

  • Task.Run(…) メソッドや ThreadPool.QueueUserWorkItem(…) メソッドの処理などには、Worker スレッドが使用されます。 これらのスレッドは、バック グラウンド スレッドで作業が発生する必要がある場合に、CLR でさまざまなコンポーネントによっても使用されます。
  • IOCP スレッドは、ネットワークからの読み取りの場合など、非同期 IO が発生する場合に使用されます。

スレッド プールは、各種のスレッドについて「最小」設定に達するまで、新しい worker スレッドまたは I/O 完了スレッドをオンデマンドで (スロットルなしで) 提供します。 既定では、スレッドの最小数はシステム上のプロセッサの数に設定されます。

既存の (ビジー) スレッドの数がスレッドの "最小" 数に達すると、ThreadPool は新しいスレッドを挿入する速度を、500 ミリ秒ごとに 1 スレッドに抑えます。 通常、ご利用のシステムで、IOCP スレッドを必要とする作業のバーストが取得された場合、その作業が迅速に処理されます。 ただし、バーストが構成済みの "最小" 設定を超えた場合は、次の 2 つの可能性のどちらかで ThreadPool が待機するので、多少の遅延が生じます。

  • 既存のスレッドの 1 つが空き状態になり、作業を処理する。
  • 既存のスレッドが 500 ミリ秒間空き状態にならずに、新しいスレッドが作成される。

基本的に、ビジー状態のスレッドの数が最小スレッド数を超える場合、アプリケーションがネットワーク トラフィックを処理する前に 500 ミリ秒の遅延が発生する可能性があります。 また、既存のスレッドが 15 秒より長くアイドル状態になると、そのスレッドはクリーンアップされ、この拡大と縮小のサイクルが繰り返されることがあります。

StackExchange.Redis (ビルド 1.0.450 以降) からのエラー メッセージの例を見れば、ThreadPool の統計情報が出力されていることがわかります。 記事の後半にある 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 であるため、クライアントには 2 つの 500 ミリ秒の遅延が表示されます。

IOCP スレッドまたは WORKER スレッドの拡大がスロットルされた場合、StackExchange.Redis がタイムアウトになる可能性があります。

勧告

IOCP スレッドと WORKER スレッドの最小構成値を既定値より大きい値に設定することをお勧めします。 1 つのアプリケーションの適切な値が別のアプリケーションに対して高すぎるか低すぎる可能性があるため、この値に関する 1 つのサイズに適合するガイダンスを提供することはできません。 この設定は、複雑なアプリケーションの他の部分のパフォーマンスにも影響を与える可能性があります。 各顧客は、特定のニーズに合わせてこの設定を微調整する必要があります。 適切な値として、まず 200 または 300 に設定し、テストして必要に応じて調整します。

この設定を構成する方法

この設定は、.NET Framework および .NET Core アプリケーションの ThreadPool.SetMinThreads (...) メソッドを使用してプログラムで変更することをお勧めします。

たとえば、NET Framework では、Global.asax.cs メソッドのApplication_Startで設定します。

```csharp
private readonly int minThreads = 200;
void Application_Start(object sender, EventArgs e)
{
    // Code that runs on application startup
    AreaRegistration.RegisterAllAreas();
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    ThreadPool.SetMinThreads(minThreads, minThreads);
}
```

.NET Core を使用している場合は、Program.csの呼び出しの直前に、WebApplication.CreateBuilder()で設定します。

```csharp
const int minThreads = 200
              
ThreadPool.SetMinThreads(minThreads, minThreads);

var builder = WebApplication.CreateBuilder(args);
// rest of application setup
```

このメソッドによって指定された値はグローバル設定であり、AppDomain 全体に影響を与えます。 たとえば、4 つのコアを持つマシンがあり、実行時に CPU ごとに minWorkerThreadsminIoThreads を 50 に設定する場合は、 ThreadPool.SetMinThreads(200, 200)を使用します。

minIoThreadsminWorkerThreads構成要素の下にあるまたは<processModel>Machine.configを使用して、最小スレッド設定を指定することもできます。 通常、Machine.config%SystemRoot%\Microsoft.NET\Framework\[versionNumber]\CONFIG\ にあります。

この方法で最小スレッド数を設定することは、システム全体の設定であるため、お勧めしません。 この方法で設定する場合は、アプリケーション プールを再起動する必要があります。

この構成要素で指定される値は、 "コアごと" の設定となります。 たとえば、4 つのコア コンピューターがあり、実行時に minIoThreads 設定を 200 にする場合は、 <processModel minIoThreads="50">を使用します。

StackExchange.Redis を使用するときにサーバー GC を有効にしてクライアントでのスループットを向上させる

StackExchange.Redis を使用するときにサーバー GC を有効にすると、クライアントが最適化され、パフォーマンスとスループットを向上させることができます。 サーバー GC とそれを有効にする方法の詳細については、次の記事を参照してください。

接続のパフォーマンスに関する考慮事項

SKU によって、クライアント接続、メモリ、および帯域幅についてさまざまな制限がある場合があります。 キャッシュのサイズごとに最大で数個の接続が許可されますが、Redis への各接続にはオーバーヘッドが伴います。 このようなオーバーヘッドの例には、TLS/SSL 暗号化による CPU とメモリの使用量があります。 指定したキャッシュ サイズの最大接続数の上限は、負荷が低いキャッシュを想定しています。 接続オーバーヘッドからの読み込みに加えて、クライアントの操作からの読み込みがシステムの容量を超える場合、現在のキャッシュ サイズが接続数の上限を超えていない場合でも、キャッシュ容量の問題が発生するおそれがあります。

各レベルの異なる接続制限について詳しくは、Azure Managed Redis の価格についてのページを参照してください。