1. ホーム
  2. c#

MemoryCacheの複数インスタンスの使用

2023-11-29 01:25:22

質問

アプリケーションにキャッシュ機能を追加したいのですが、それには System.Runtime.Caching 名前空間を使用したアプリケーションにキャッシュ機能を追加したいのですが、おそらく複数の場所と異なるコンテキストでキャッシュを使用したいと思います。 そうするために、いくつかの MemoryCache インスタンスを使用したいと思います。

しかし、私は はここで を見ると、MemoryCache の複数のインスタンスを使用することは推奨されないことがわかります。

MemoryCache はシングルトンではありませんが、少数の、あるいは潜在的には1つの MemoryCache インスタンスのみを作成し、アイテムをキャッシュするコードはそれらのインスタンスを使用する必要があります。

複数の MemoryCache インスタンスは、私のアプリケーションにどのような影響を与えるでしょうか? アプリケーションで複数のキャッシュを使用することは、かなり一般的なシナリオのように思えるので、これはちょっと奇妙なことだと思います。

EDITです。 具体的には、各インスタンスのキャッシュを保持するクラスがあります。私は MemoryCache の使用を避け、別のキャッシュソリューションを探すべきでしょうか?というのは MemoryCache を使用することは悪いことなのでしょうか、もしそうなら、それはなぜでしょうか?

どのように解決するのですか?

私自身も最近この問題に直面しました。イン メモリ キャッシュがプロセス固有である (Web サイトやネイティブ ビジネス アプリの複数のインスタンスや複数のサーバーで共有されない) ことを考慮すると、複数の MemoryCache インスタンスを複数持つことの利点は、コード整理の理由 (これは他の方法で達成できます) を除いてはありません。

メモリキャッシュは、そのメモリ管理機能により、単独で使用されることを意図しています。パフォーマンス カウンター (多少のオーバーヘッドがあります) に加えて、MemoryCache は割り当てられたメモリを使い切ったときにアイテムを失効させることができます。

キャッシュの現在のインスタンスが、CacheMemoryListenerによって設定されたメモリの制限を超えた場合、そのインスタンスは破棄されます。 CacheMemoryLimit プロパティによって設定されたメモリの制限を超えると、キャッシュの実装はキャッシュエントリを削除します。 キャッシュの実装はキャッシュエントリーを削除します。アプリケーションの各キャッシュインスタンスは CacheMemoryLimit プロパティで指定された量のメモリを使用できます。

から MemoryCache.CacheMemoryLimitプロパティ

MemoryCache のインスタンスを 1 つだけ使用することで、アプリケーションのインスタンス全体にわたってこのメモリ管理を効率的に適用することができます。アプリケーション全体にわたって、最も重要でない項目が失効します。これにより、ハードウェアの能力を超えることなく、最大のメモリ使用量を確保できます。一つの MemoryCache の範囲を限定することで、(例えばクラスの一つのインスタンスに)アプリケーションのメモリを効果的に管理することができなくなります(すべてを見ることができないため)。これらのキャッシュのすべてが「ビジー」であった場合、メモリの管理が難しくなり、効率はほとんど良くなりません。

これは、専用サーバーの余裕がないアプリケーションでは特に敏感です。150mb の RAM しか割り当てられていない共有サーバーでアプリケーションを実行していると想像してください (一般的な $10/month の安価なホスティング)。このメモリ使用量を超えると、アプリのプールがリサイクルされ、アプリはメモリ内のキャッシュをすべて失います。(同じことが、社内の共有サーバーでホストされている非ウェブアプリにも当てはまります。同じように、そのマシン上のすべてのメモリを占有しないように、そして他のビジネス用アプリと平和的に共存するように言われます。

このメモリ制限、アプリ プールのリサイクル、キャッシュの喪失は、Web アプリに共通するアキレス腱です。アプリが最も忙しいとき、メモリ割り当てを超えたために最も頻繁にリセットされ、すべてのキャッシュ エントリが失われ、その結果、最初の場所でキャッシュされているはずのものを再取得するために最も多くの作業が発生します。つまり、アプリは最大負荷時にパフォーマンスを向上させるのではなく、低下させるのです。

MemoryCache が System.Web.Caching.Cache 実装の非 Web 固有のバージョンであることは知っていますが、これは、キャッシュ実装の背後にあるロジックを示しています。ハードウェアを排他的に使用しない場合、同じロジックが非 Web プロジェクトで適用できます。もし、キャッシュがマシンにページファイルのスワップをさせるなら、キャッシュはもはやディスク上のキャッシュより速くならないことを忘れないでください。たとえ、その制限が2GBとかであっても、常にどこかで制限をかけたいものです。

私の場合、このことについて調べた後、私のアプリでは1つの 'public static MemoryCache' を使用するように切り替え、キャッシュされたアイテムをキャッシュキーで単純に分離しました。例えば、インスタンス単位でキャッシュしたい場合は、"instance-{instanceId}-resourceName-{resourceId}" のようなキャッシュキーを持つことができます。これは、キャッシュエントリーの名前間隔と同じだと考えてください。

お役に立てれば幸いです。