拡張メソッドを介したEFコアでの.NETキャッシングの使用

録画されたウェビナー
ロン・フセインとニック・ズルフィカール

Entity Framework (EF) Core は、Microsoft の人気のある Entity Framework の新しいクロスプラットフォームの軽量バージョンです。 EF Core は、開発者が作成するデータ アクセス コードのほとんどを不要にする .NET 用のオブジェクト リレーショナル マッピング エンジンです。

EF Core は、高トランザクション サーバー アプリケーション (ASP.NET、WCF、およびその他の .NET サーバー アプリ) で使用されることが増えています。 また、これらのアプリケーションには、速度を低下させることなく大量のユーザー要求を処理するためのスケーラビリティが必要です。 ただし、データベースがボトルネックになるため、このボトルネックを解消するには分散キャッシュを使用する必要があります。

次のような分散キャッシュの使用方法を学ぶ NCache 自分で EFコアアプリケーション データベースのスケーラビリティのボトルネックを取り除くために。

このウェビナーでは、次のような実践的なソース例を取り上げます。

  • EF Core とその新機能 (モデル、クエリ、データの保存) の概要
  • EF Core のデータベース スケーラビリティのボトルネックと分散キャッシュがそれらを解決する方法
  • さまざまな使用オプション NCache EF Core 内 (ダイレクト API および EF Core 拡張メソッド)
  • キャッシュのための EF Core 拡張メソッドの使用の詳細
  • 参照データとトランザクション データのコレクションとリレーションシップのキャッシュを処理するにはどうすればよいですか?
  • 優れた分散キャッシュの重要な機能としては、次のようなものがあります。 NCache

EF Core は、.NET 用のオブジェクト リレーショナル マッピング エンジンであり、 .NET Core アプリケーション。 これにより、開発者は、通常は自分でコードを記述する必要があるデータ アクセス コードを自動的に生成できます。 に似ている .NET Core, EF Core はクロスプラットフォームでもあり、Windows、Linux、Mac 上で実行できることを意味しており、開発者コミュニティで非常に人気が高まっています。

このウェビナーでは、EF Core アプリのパフォーマンスとスケーラビリティのニーズについて説明し、EF Core 拡張メソッドを使用して参照データとトランザクション データをキャッシュするためのさまざまな戦略を示します。 典型的な EF Core アプリケーションで直面するパフォーマンスとスケーラビリティの課題とは何ですか。次に、Entity Framework Core アプリケーション内でキャッシュを使用するさまざまなオプションについて説明します。

ここでは主に、Entity Framework コア アプリケーション用に実装した拡張メソッド、EF 拡張メソッドに焦点を当てます。 そこで、Entity Framework のコア拡張メソッドをすべて見ていきます。 NCache 次に、Nick が提案したように、参照データとトランザクション データを処理するためのさまざまな戦略について説明します。 また、分散キャッシュの使用を開始するときにデータが XNUMX つの異なる場所に存在する場合に、データの同期を保つ方法についても説明します。 これが今日のウェビナーの議題です。 早速始めます。 カバーしなければならないことがたくさんあります。 紹介したい実践例がたくさんあります。 それでは、早速始めましょう。

Entity Framework / EF Core とは何ですか?

したがって、最初のスライドは Entity Framework と EF Core についての紹介に近いものになります。

エンティティ フレームワーク コアとは

EF および EF Core、これは .NET 用のオブジェクト リレーショナル マッピング エンジンであり、 .NET core アプリケーション。 Entity Framework の最新バージョンは EF Core という名前です。 ご存じのとおり、最近 EF Core 2.1 がリリースされました。 .NET Core 2.1. ご存知のとおり、これによりデータベース プログラミングが簡素化されます。 データ アクセス モデルを自動的に生成できるようになります。 したがって、それを自分で書く必要はありません。 そのために必要な開発労力が削減されます。 通常は ADO.NET レベルで自分で記述するような永続化コードを記述する必要はなく、データ モデルとオブジェクト モデルの間でマッピングを行う必要があります。 つまり、それを最適化するだけです。

したがって、非常に柔軟です。 開発者コミュニティとそのクロスプラットフォーム内で非常に人気があり、.NET とそのクロスプラットフォームでも非常に人気があります。 .NET Core アプリケーション、特に大量のリクエスト負荷を処理する高トランザクション アプリケーション。

Entity Frameworkのアーキテクチャ図

これはEntity Frameworkのアーキテクチャ図です。

アーキテクチャ図

ご存知のとおり、これは EF Core にも適用されます。 EF と EF Core の間にはほとんど違いがありません。 EF Core は軽量に作られています。 モジュラーアプローチを採用しています。 多くのことはなく、完全なインストールを実行する必要はありません。 モジュール式のアプローチを採用できます。 小さなパッケージに分解されているので、興味のあるパッケージを操作できます。

そのため、完全なインストールを行う必要はなく、.edmx とそれらのマッピング ファイルも削除されています。 つまり、NuGet パッケージといくつかのコマンドを実行するとモデルが生成され、アプリケーション層で LINQ to Entities API を操作するだけで、全体的なアプローチは変わりません。

スケーラビリティとは何ですか?

通常、EF Core アプリケーションでは、パフォーマンスとスケーラビリティの要件について説明します。 スケーラビリティは、アプリケーションが処理しなければならないリクエストの量を増やすことができるアプリケーション内の機能です。 たとえば、ユーザーの負荷が増加したり、リクエストの負荷に貢献しているユーザーがアプリケーション内で増加したり、アプリケーションの速度が低下したりすると、そのアプリケーションはスケーラブルではなくなります。

したがって、ピーク負荷時の高いパフォーマンスは、スケーラビリティとして分類されます。 アプリケーションが XNUMX ユーザー未満でミリ秒未満の遅延で非常に良好なパフォーマンスを示している場合、たとえば XNUMX ユーザーや XNUMX ユーザー以下でも、同じ種類のパフォーマンス、同じ種類の遅延、低い遅延が得られるはずです。リクエストの負荷。

つまり、高いストレス負荷やピーク負荷の下での高いパフォーマンス、これがスケーラビリティと分類されるものです。 EFコア。

スケーラビリティが必要なアプリケーションは何ですか?

アプリケーションに必要なスケーラビリティ

ASP.NET Web アプリケーションである可能性があります。 ASP.NET または ASP.NET Core 多くのリクエストに対応している可能性があります。 それは .NET である可能性があります。 .NET Core Web サービス、再び Web サイト上で。 次に、IoT サーバー アプリケーションがあります。 繰り返しになりますが、.NET または .NET Core またはその他の一般的な .NET および .NET Core 独自のドメインで大量のリクエストまたはユーザーを処理する可能性のあるアプリケーション。

したがって、これらはスケーラビリティの候補です。

スケーラビリティの問題は一体どこにあるのでしょうか?

通常、EF と EF Core は Web ファームにデプロイされます。 Web アプリケーションの場合、直線的に拡張されます。 アプリケーション層にはスケーラビリティの問題はありませんが、常にバックエンドのリレーショナル データ ソースと通信する必要があります。 SQL Server である可能性があります。 Oracle Server の場合もあれば、EF または EF Core でサポートされているその他のデータ ストレージの場合もあります。 EF Core には多くのデータ プロバイダーがあります。 選択できるプロバイダーのリストがあります。 したがって、最終的にはデータベースと通信することになります。

アプリケーション層は適切にスケールアウトしますが、このデータ ストレージ、データベース、リレーショナル データベースが競合の原因になります。 インメモリではないので起動が遅いです。 EF Core はインメモリ データ プロバイダーを考案しましたが、これは InProc、ストアであり、ローカル テスト用です。 これによりテストは容易になりますが、アプリケーションが運用環境にデプロイされると、速度が遅くスケールアウトしないリレーショナル データベースを処理する必要があります。 これはストレージとしては非常に優れていますが、アプリケーション内で実際にスケーラビリティが必要な場合にはスケールアウトできません。

つまり、極度の負荷がかかると窒息する可能性がある単一の原因になります。

ソリューション

解決策は非常に簡単で、次のような妨害されたキャッシュ システムを使用し始めるだけです。 NCache、EF コア アプリケーションの場合は、それをリレーショナル データベースと組み合わせて使用​​します。

デプロイメントアーキテクチャ

デプロイメントアーキテクチャは次のとおりです NCache.

導入アーキテクチャ

まず第一に、それはメモリ内です。 つまり、比較すると超高速です。 次に、通常はバックエンドのリレーショナル データ ソースからフェッチできるデータを保存する複数のサーバーがあります。 それをキャッシュに取り込むことができ、それは ASP.NET または ASP である可能性があります。.NET Core アプリ、.NET または .NET、Web サービス、または .NET または .NET Core サーバー アプリケーションまたはあらゆる種類の .NET または .NET Core アプリケーション、さらには Java アプリケーションでも、この分散キャッシュ システムを利用できます。 リレーショナル データ ソースへの高価な移動を節約できます。 メモリ内にあります。 さらにサーバーを追加し、このキャッシュ クラスターの容量を直線的に拡張できます。

したがって、単一障害点ではありません。 それはパフォーマンスではなく、ボトルネックです。 それはスケーラビリティのボトルネックではありません。 したがって、これが推奨されるアプローチであり、今日は .NET キャッシュの使用方法について詳しく説明します。 NCache 拡張メソッドを使用した EF Core アプリケーションのサンプル製品として。

一般的に使用される 3 つの分散キャッシュの使用例

分散キャッシュの使用例

分散キャッシュの一般的な使用例をいくつか示します。 データのキャッシュに使用できます。 直接 API 呼び出しを使用できます。 または、EF Core アプリケーションに対しても Entity Framework または拡張メソッドを使用すると、データベースへのアクセスをできるだけ節約できます。

次に、Web サイト、つまり物事の Web サイトには、ASP.NET、ASP があります。.NET Core キャッシング。 それは Web アプリケーションまたは Web サービスである可能性があります。 Web アプリケーションの場合は、セッションを使用したい場合があります。 ASP.NET と ASP を使用することもできます。.NET Core SignalR Backplane、ASP の応答キャッシュ.NET Core。 同様に、IDistributedCache インターフェイス、ビューステートおよび出力キャッシュが利用可能です。 これらはすべて、アプリケーションのコードなしのオプションです。

さらに、強力な Pub/Sub メッセージングも利用できます。 トピックを購読して、異なるアプリケーション間でメッセージを共有することができます。 パブリッシャーとサブスクライバーは相互にメッセージを送信できます。

つまり、それが一般的な考え方です。 今日は EF Core アプリケーション内でのデータ キャッシュにさらに焦点を当て、開始するための簡単な手順を説明します。その後、実際にさらに拡張して、さまざまなシナリオについてさらに詳細を共有します。

それでは、早速始めてみましょう。

APP データ キャッシュ: EF Core エンティティ

今日最初に取り上げたいのは、アプリケーション データ キャッシュです。

キャッシュするコアエンティティの内容

EF Core エンティティがあります。 したがって、それらのエンティティをキャッシュする必要があります。 したがって、単一のエンティティが表示される場合があります。 たとえば、カウント、合計があるとします。 それは値です。あるいは、並べ替えを行って最初の顧客を取り出したり、単一の顧客、単一の製品、単一の注文を返すような基準を指定したりすることもできます。 では、これは単一のエンティティですが、どのようにキャッシュするのでしょうか? 同様に、エンティティ コレクションである可能性のあるクエリ結果もあります。 したがって、それは単一の実体ではありません。 それはエンティティのコレクションです。 選択肢は XNUMX つあります。 コレクション全体を XNUMX つのアイテムとしてキャッシュにキャッシュすることも、各コレクション アイテム、そのコレクション内の各エンティティを分散キャッシュに個別にキャッシュすることもできます。

EF Core エンティティ キャッシュ オプション

そこで、このあたりのアプローチを見ていきましょう。

efcore-entity-caching-options

前に説明したように、直接使用できます NCache API。 NCache API はキーバリューストアであり、データを追加します NCache 自分自身でそれから受け取ることも、EF Core 拡張メソッドを使用して、この単一のエンティティとエンティティ コレクションを担当することもできます。

それでは、まず直接お見せしましょう NCache あらゆる種類のアプリケーションに共通する API アプローチ。 EF Core で使用できます。 これは通常の EF またはその他の .NET アプリケーションで使用できます。次に、EF Core アプリケーション用に特別に設計された EF Core Extension メソッドについて説明します。これにより、多くのことが自動的に実行されるため、作業が大幅に楽になります。クエリとともにこの拡張メソッドを呼び出すだけです。 そこで、これらの両方のアプローチを XNUMX つずつ紹介し、その後、拡張方法にさらに焦点を当てていきます。

EF Core 単一エンティティのキ​​ャッシュ: NCache 直接API

したがって、最初の例は、EF Core の単一エンティティをキャッシュすることです。

Customers GetCustomer (string CustomerId)
{
	string key = "Customer:CustomerId:" + CustomerId;
	Customers customer = (Customers)_cache.Get(key);
	
	if (customer != null)
	{
		return customer;
	}
	else
	{
			customer = (from cust in database.Customers
					where cust.CustomerId == CustomerId
					select cust).FirstOrDefault();
                    _cache.Insert(key, customer);
	
		return customer;
}
}

ここに GetCustomer メソッドがあります。 このために私が作成したサンプル アプリケーションを使用してこれを示します。 したがって、これが最初の方法です。 私の画面を見ていただければ幸いです。 つまり、Get Customer があります。 これは顧客 ID を取得しており、これは単一のエンティティを返しているということになります。 したがって、通常、直接 API では、考慮すべきこと、または何かを自分で実装する必要があるという課題があります。

まず第一に、キーを持っている必要があります。そのキーは内部のエンティティを識別するものです。 NCache すべてのキーを同じ形式に維持する必要があります。 画面に表示されているように、サンプル形式を作成できます。 顧客キーワード、顧客 ID、およびキャッシュ キーを作成する顧客 ID の実行時パラメータがあります。

In NCache すべてはキーと値のペアに保存されます。 キーは文字列キー、値は .NET で許可されたオブジェクトであり、任意の EF Core エンティティでも構いませんが、キーを作成してから、そのエンティティを格納されるオブジェクトとして使用します。 NCache。 ここで、まず、cache.Get を呼び出して、そのキーがすでにキャッシュに存在するかどうかを確認します。また、その顧客をキャッシュから直接取得するかどうか、これは直接の取得であるかどうかを確認します。 NCache APIのcache.Getでは、キーを渡し、その顧客を取得したら、ここからコードを返します(それがnullでない場合)。 ただし、たとえば null の場合は、そのクエリを初めて実行することになり、まだキャッシュには何もありません。 したがって、その場合、Entity Framework Core、データベースに対して LINQ API を実行し、データベースからその顧客を取得し、cache.Insert を呼び出し、作成したのと同じキーを使用してそれを保存します。そうすると、顧客は追加したいエンティティを追加し、それを返します。

したがって、これが、適切な API を使用して単一のエンティティを実際に処理する方法です。

EF Core エンティティ コレクションのキャッシュ: NCache 直接API

それからコレクション。 コレクションは、単一のオブジェクトとしてのコレクション、または単一のエンティティとしてのコレクションのいずれかになります。

List<Customers> GetCustomersByCity (string CustomerCity)
{
	string key = "Customers:City = " + CustomerCity;
	List<Customers> custList;
    custList = (List<Customers>)_cache.Get(key);

	if (custList != null)
	{
		return custList;
	}
	else
	{
		custList = (from cust in database.Customers
					where cust.City == CustomerCity
					select cust).ToList();

		_cache.Insert(key, custList);
		return custList;
	}
} 

各コレクション エントリは、キャッシュに個別に追加された単一のエンティティである可能性があります。 そのために都市ごとに顧客を取得しました。それが次の方法です。 顧客のリストを返しています。 繰り返しになりますが、顧客の都市を基準として渡しています。 もう一度、キーを作成します。 繰り返しますが、これは都市に基づいた顧客のコレクションを表しており、この都市はランタイム パラメーターになる可能性があります。 ニューヨーク、パリ、ロンドン、そして最初にcacheを呼び出してフェッチします。自分でキャッシュから取得してから、キャッシュに存在するかどうかを確認し、存在する場合はここから戻り、存在しない場合は単純にキャッシュとして保存します。シングルコレクション。

したがって、この顧客のリストは XNUMX つのオブジェクトとして保存されます。 他の代替方法としては、顧客エンティティ内の個々の顧客のリストを反復処理し、ここに示すようにキャッシュを個別に挿入することもできます。 右? したがって、直接を使用する単一エンティティとエンティティ コレクション NCache API は、これらのアプローチを使用してキャッシュされます。 ここまでは直接 API について説明しました。 これはあらゆるアプリケーションで使用できるものです。

EF Core 単一エンティティのキ​​ャッシュ: EF Core 拡張メソッド

Entity Framework のコア拡張メソッドに焦点を当てましょう。 したがって、単一のエンティティとエンティティ コレクションも同様です。 NCache 拡張メソッド。 ということでFromCacheを紹介します。

Customers GetCustomer (string CustomerId)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};
	
	Customers customer  = (from cust in database.Customers
							where cust.CustomerId == CustomerId
							select cust).FromCache(out string cacheKey,
                            options).FirstOrDefault();
	return customer;
}

これが最初の拡張メソッドです。ところで、この拡張メソッドを使用するには、まず次のことを導入する必要があります。 NCache NuGet パッケージ アプリケーション内の Entity Framework コア NuGet パッケージ。 したがって、それは必須です。 インストールされた場所に移動すると、これは Alachisoft.NCache.EFCore NuGet パッケージ。 これがアプリケーション内に導入する必要があるものであり、その後はコンテキストを開くだけで済みます。 したがって、コンテキスト内で単に呼び出すだけです NCacheConfiguration.Configure では、アプリの設定から読み取るキャッシュ ID を取得し、依存関係を使用している場合は、Entity Framework Core 拡張メソッド内の高度な機能であるタイプも取得します。 データ ソースのタイプを指定する必要があります。

しかし、一度電話をかけてしまうと、 NCache Configure メソッド、このメソッドが要求するものはさまざまです。 ロガーを設定することもできますが、それだけです。 これにより通話を開始できるようになります NCache, アプリケーション内の EF Core 拡張メソッド。

EF Core エンティティ コレクションのキャッシュ: EF Core 拡張メソッド

つまり、メソッドは同じですが、今回は拡張メソッドを通じて顧客を獲得します。

List<Customers> GetCustomersByCity (string CustomerCity)
{
	List<Customers> custList; 
	CachingOptions options = new CachingOptions
	{	
		StoreAs = StoreAs.Collection
	};
	custList = (from cust in database.Customers
				where cust.City == CustomerCity
				select cust).FromCache(out string cacheKey,
                options).ToList();
	return custList;	
}

すべてがずっとシンプルになります。 キャッシュ内のデータを自分でチェックする必要はなく、insert を自分で明示的に呼び出す必要もありません。そして最も重要なことに、呼び出す必要がなく、キャッシュ キーを自分で構築する必要もありません。 これは、この「FromCache」の実装の一部として完全に自動化されています。

さて、行動の観点から見ると、これはまさに以前に示したものです。 FromCache は、まずキャッシュ オプションを受け取ります。オプションと 'cacheKey' は出力参照です。 したがって、バックグラウンドでキャッシュ キーを自動的に構築します。 拡張メソッドとしてクエリと一緒にキャッシュから呼び出す必要があるだけで、常にコレクションを返す場合の保存オプションを渡すだけです。 したがって、その場合は、別個のエンティティまたは別個のコレクションのいずれかを選択できます。 したがって、エンティティのコレクションである場合もあれば、そのコレクションからの別個のエンティティである場合もあります。

そのため、FromCache は、エンティティ、または実行したクエリとその結果のエンティティがすでにキャッシュ内にある場合、キャッシュからそれを取得するように機能します。 NCache 自動的に。 ただし、その場合にキャッシュにない場合は、データベースに対してそのクエリが自動的に実行され、結果セットが返され、同時にそれもキャッシュされ、後続の呼び出しのためにデータベース コンテキストもアタッチされます。

たとえば、FromCache を初めて呼び出すと、それがキャッシュされます。 次回同じクエリを実行するときは、明らかにキャッシュに対して実行されますが、データベースに対しては実行されません。 今回は、コンテキストが以前に破棄されており、このリクエストで using コンストラクトを使用していた場合、エンティティに変更を加えた場合、その変更もコンテキストに添付されます。 そして、Save Changes を呼び出すと、キャッシュから取得されたエンティティに対して行われたすべての変更が実際にデータベースに適用されます。 これは、少し、また少し高度な概念です。 後の段階でもう少し時間をかけて説明しますが、from Cache メソッドは、何かがキャッシュにない場合にデータベースから取得してキャッシュするように機能することを知っておいてください。 ただし、何かがすでにキャッシュ内にある場合は、そこからそれを返すだけです。 したがって、これにより、直接的な API アプローチ全体が自動化されますが、キーの構築も行われます。 また、データは別のエンティティまたは別のコレクションに自動的に編成され、キャッシュから呼び出して out キーとオプションを渡すだけで済みます。

コレクションの場合も同様です。 コレクションの場合は、都市ごとに顧客を取得します。 これはコレクションとして保存され、再びキャッシュから呼び出すことができます。 このように、Entity Framework Core 拡張メソッドを使い始めるのはとても簡単です。

EF Core にキャッシュするデータは何ですか?

次のトピックは、再びキャッシュ内のデータの種類と使用方法です。

efcore でキャッシュするデータ

参照データまたはトランザクション データのいずれかを使用できます。 質問はありますか?

そうだ、ロン、ここで質問があるんだ。 の拡張メソッド NCache EF Core で動作することをお勧めします .NET Core 2.0 フレームワークまたは .NET Framework?

大丈夫。 つまり、EF Core 自体は .NET でも実行できるため、 .NET Coreなので、非常に柔軟です。 NCache 拡張メソッドはまったく問題なく動作します。 実際、私はこのサンプル アプリケーションを実行しています .NET framework 4.6.1 と私は別のサンプル アプリケーションを持っています。 .NET core 2.0。 それで、これは .NET Core 2.0。 したがって、両方で動作します .NET framework基本的には使用することをお勧めします .NET Core、しかし、それは柔軟です。 どちらにも効果があります。 それがあなたの質問の答えになることを願っています。

次に、プレゼンテーション内の次のセグメントでは、適切なキャッシュの計画を開始します。明らかに、エンティティ フレームワークのコア拡張メソッドにより、キャッシュの面で作業がはるかに簡単になります。 つまり、実際には多くのことが自動的に行われます。 さて、次の疑問はどのデータをキャッシュするかということですよね?

そこで、データを 100 つのカテゴリに分類しました。 参考データがございます。 これはルックアップ データであり、動的に作成され、非常に頻繁に変更されるトランザクション データが得られます。 参考データとしては、簡単な例としては製品や従業員などが挙げられます。 これは 1% 静的なデータではありませんが、それほど頻繁には変更されないものです。 ただし、変化はありますが、変化の頻度はそれほど大きくありません。 このためには、参照データ全体をキャッシュすることを計画する必要があります。 すべての参照データは必須としてキャッシュされる必要があり、トランザクション データは動的に作成されるデータです。 注文、アカウント、データの特定のコレクションに対する一部のワークフロー処理など、そのコレクションの範囲はそのワークフローのみに適用されます。 ワークフローの実行が完了すると、そのデータは不要になり、このデータも頻繁に変更される可能性があります。 それほど、2分以内に変化する可能性があります。 一方、参照データは通常、時間ごとに変化する可能性のある参照データです。 5 ~ 10 時間、XNUMX ~ XNUMX 時間、または数日かかる場合もあります。

ここで質問があります。 自動的に作成されたキーと同じように EF 拡張機能を使用して取得する場合、このキャッシュされたオブジェクトをどのように識別しますか? 実際には、特定のキーを取得するのではなく削除するのでしょうか?

大丈夫。 したがって、取得用の拡張メソッドがあります。拡張メソッドは EF Core とともに実行されます。 したがって、戻りオブジェクトは、LINQ クエリが識別するのと同じ行で識別されます。 質問は、レコードの更新を計画しているときに何が起こるかに焦点を当てていると思います。そのための一連の API があります。 エンティティに対してキーを生成できるメソッドを提供します。 弊社が公開した鍵生成方法があります。 したがって、キャッシュに直接変更を加える前に、この質問はキャッシュ内の何かを削除するか、キャッシュ内の何かを更新するか、キャッシュ内の何かを明示的に削除または追加することに重点を置いていると思います。 キャッシュ クラスを公開しました。これについては後ほど説明します。その後、キーの生成があります。 繰り返しますが、文字列を渡し、out 参照を使用してエンティティも渡します。 したがって、そのエンティティに対しても同じアプローチを使用し、キーを提供します。そのキーを使用して、そのエンティティのオブジェクトを識別できます。キャッシュ内に存在する場合は、更新および削除できるはずです。

最後の方でそれを実現する方法の例を紹介したいと思いますが、私たちが暴露された方法があることを知っておいてください。 NCache 同じように。 あなたの質問に答えられることを願っています。

EF Core での参照データのキャッシュ

次に進みます。 ここまで、データの検索と、データの動的作成について説明してきました。

EFコア内のキャッシュ参照データ

したがって、これに対処するためのさまざまなアプローチを XNUMX つずつ説明します。 そこで、まず EF Core の参照データについて説明します。 前述したように、これは通常、ルックアップ データです。 したがって、必ずやるべきことが XNUMX つあります。 まず第一に、必須としてデータ全体、参照データ全体をキャッシュにロードする必要があります。ここでの動機は、このデータがそれほど頻繁に変更されないものであるためです。 これは、EF の電子商取引アプリケーションの製品カタログです。 特定の製品にはいくつかの割引があり、その割引はたとえば XNUMX 日間有効です。 これらの製品は変更されない可能性があるため、それらの製品をすべてキャッシュすることをお勧めします。 NCache そして、その範囲での高価なデータベースの移動を可能な限り節約します。 100% の場合、データはキャッシュにロードされます。 そのため、データ ソースに戻って、常にそれらを別のエンティティとしてキャッシュする必要がなくなります。 なぜ? 製品なので、データセット全体が何千もの製品になる可能性があります。

たとえば、Northwind データベースとしましょう。 製品は 50,000 ~ 100,000 の範囲に及ぶ可能性があります。 ただし、特定のリクエストに対して必要なのは、たとえば、そのうち 10 個または 100 個だけかもしれません。 したがって、それらを別のエンティティとして保存すると、LINQ クエリを実行できます。 NCache LINQ もサポートしています NCache 直接。 したがって、エンティティのサブセットをクエリしてデータのサブセットを取得する際に LINQ を実行できます。 NCache 同様に。

したがって、これらは必須として従うべき XNUMX つのルールです。例を示します。ここでは XNUMX 番目の拡張メソッドである Load Into the Cache を紹介します。

EF Core での参照データのキャッシュ: 事前読み込みキャッシュ

さて、これはこのように機能し、参照データのみを対象としています。 これはキャッシュへのプリローダーです。

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};	
	
	// Loads all products into cache as individual entities
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();
}

したがって、ここでの動機は、このメソッドを呼び出す必要があることです。たとえば、「すべての製品をロード」すると、それを別のエンティティとして保存していることを確認し、データベース内の製品から製品を指定して製品を選択するというクエリを実行する必要があります。 。 つまり、条件を指定していないということは、60,000 個の製品すべてがキャッシュに読み込まれてから、LoadIntoCache を使用しているということですね。 個別のエンティティと言う場合は、このオプションを渡すだけで済みます。キャッシュ内の製品ごとに個別のエンティティを作成するだけです。これもプリローダーです。 これをプリロードする必要があります。

選択肢は XNUMX つあります。 このために、キャッシュの事前ロードを担当できる別のアプリケーションを実行できます。 これは、アプリケーションの起動または別のアプリケーションである可能性があります。または、キャッシュ ローダーの実装である可能性もあります。 NCache 同じように。 キャッシュ ローダーがあり、将来のリリースではキャッシュ リフレッシャーも機能するようになります。

キャッシュ ローダーの役割は、キャッシュの起動時に実際に実行され、キャッシュにロードするすべてのデータがその一部としてロードされることを確認することです。 それはあなたの実装ですが、 NCache 単にそれを呼び出すだけです。 ただし、前述したように、このようなメソッドを考え出して、アプリケーションの起動時に必ず XNUMX 回呼び出すか、別のアプリケーションにこれを実行させて、すべてのアプリケーション インスタンス間でこのデータを共有することができます。

これが完了したら、その時点でキャッシュからデータをクエリする方法を説明します。 XNUMX 番目の拡張メソッドである From Cache Only を紹介します。

EF Core での参照データのキャッシュ: キャッシュのみから参照データを検索する
List<Products> FindDiscontinuedProducts (NorthwindContext database)
{
	//Fetch discontinued products only out of all products 
	List<Products> discontinuedProducts;
	
	discontinuedProducts = (from product in database.Products 
   	 where product.Discontinued == true
   	 select product).FromCacheOnly().ToList();
	
	return discontinuedProducts;

}

そこで、最初の拡張メソッドは FromCache で、キャッシュに何かがある場合はそこから取得します。 そうでない場合は、自動的にデータベースにアクセスして取得します。 LoadIntoCache は常にデータベースに対して実行されます。 これは返されてもキャッシュに対して実行されることはありませんが、データセットが更新されるように必須としてデータベースから返されます。 新しいデータがロードされてキャッシュも行われ、FromCacheOnly は次のデータに対してのみ実行されます。 NCache これは参照データのみを目的として設計されているためです。 したがって、参照データの場合は、LoadIntoCache を組み合わせて使用​​します。 そのため、すべてのデータセットが個別のエンティティとしてキャッシュに存在し、FromCacheOnly を呼び出して、関心のあるデータセット、つまりこの場合は廃止された製品のみがキャッシュから取得されるようにします。 したがって、データベースにアクセスする必要はまったくありません。 データベース内のデータが変更されたときに、このデータを最新の状態に保つ方法について説明します。 したがって、これが理にかなっていることを願っています。 この例をここでお見せしましょう。

したがって、ここでこのメソッドを呼び出して、単純な EF、LINQ API を直接使用して、製品のリスト、販売終了した製品のリストを返しています。 NCache エンティティ。

したがって、これはデータベースに対してはまったく実行されません。 FromCacheOnly 拡張メソッドを使用しているため、これはキャッシュに対してのみ実行されます。 これがお役に立てば幸いです。 XNUMX つの拡張メソッド、つまりトランザクション データの使用例である FromCache について説明し、次に LoadIntoCache と FromCacheOnly について説明しました。 参照データの場合は、LoadIntoCache を使用してデータ全体を使用することに重点を置き、次にエンティティを分離し、クエリの場合は FromCacheOnly を使用する必要があります。

EF Core でのトランザクション データのキャッシュ

次に、トランザクション データについて説明し、次にこのデータを参照用とトランザクション用の両方で最新の状態に保つ方法について説明します。

efcore のトランザクション データのキャッシュ

さて、トランザクション データは通常、ワーキング セットです。 これが動的に作成されたデータであることはすでに説明しました。 現在のユーザー、現在のリクエスト、またはワークフローが実行されている場合にのみ必要であり、一度実行されると、そのデータは必要なくなる可能性があります。 したがって、実際にそのデータを取得するアプリケーションのインスタンスだけが、それらのエンティティを必要とする可能性があります。 したがって、すべてのトランザクション データをキャッシュに保存することは意味がありません。 それは必須ではありません。 ワーキングセットのみをキャッシュする必要があります。 それがステップ 2 です。 したがって、クエリ結果をキャッシュする必要があります。 最も簡単にアクセスできるエンティティをフェッチできます。2 番目のステップでは、XNUMXa、XNUMXb の XNUMX つのオプションがあります。

フェッチしてコレクションとしてキャッシュする

トランザクション データをコレクション全体としてキャッシュできます。 それは好ましいアプローチです。

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection,
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	
	return orderList;
}

通常、コレクション全体を常に必要とします。これは、コレクションに取り組んでいて、個別のエンティティも保存できるためです。 これは完全にユーザー次第で、コレクションをキャッシュしたものの、そのコレクションから必要なエンティティは XNUMX つまたは XNUMX つだけであるため、それを別のエンティティとして保存するシナリオが対象です。 したがって、コレクションを保存するときは、きめ細かなアプローチをとる方が良いため、GetCustomerOrders を使用します。 注文は非常にトランザクション的なデータです。 特定のオーダーを処理する処理ユニットが存在する必要があり、それを実行している各ワークフローが独自のオーダーのセットを持っている可能性があります。

それでは、この例をすぐにお見せします。 したがって、多くのキャッシュ オプションを追加するような方法で機能しています。 ここでは実際には詳細に立ち入りません。 コレクションとして保管します。 これが、コレクションとして保存することを選択する方法であり、私は FromCacheOnly を使用しています。 トランザクション データの理由は、データがキャッシュ内に存在する可能性があり、コレクション全体に存在する場合はそれを使用するだけで済むため、FromCache を使用しているからです。 データベースに行く必要はありません。 ただし、キャッシュにデータが存在せず、このデータも非常に頻繁に変更される場合は、有効期限 (たとえば 30 秒) も設定されているため、データベースに戻ることをお勧めします。 FromCacheOnly を使用すると、キャッシュに存在しない場合、またはすでに有効期限が切れている場合に null 値を返すことができます。

したがって、トランザクション データの場合は拡張メソッド From Cache を使用し、参照データの場合は LoadIntoCache を使用してプリロードしてから FromCacheOnly を使用します。 したがって、それがそれに取り組むためのアプローチです。

フェッチとキャッシュを別個のエンティティとして行う

個別のエンティティの場合は、保存してこれを呼び出すだけです。

List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs.SeperateEntities
	};

	//Fetch from cache. If not found then fetch from DB.
	orderList = (from customerOrder in database.Orders 
				where customerOrder.Customer.CustomerId==CustomerID 
				select customerOrder)
				.FromCache(out string cacheKey, options).ToList();
	return orderList;
}

これを使用して、別個のエンティティを使用する代わりに、(コメントする必要があるのでコメントする必要があります) そうですね、別個のエンティティとして保存します。 やるべきことはこれだけです。

それで、ロン、これを検討している間に質問があります。 前の例では、参照データをクエリしていますが、インデックスは作成されていますか? なぜなら、それをデータベース上で作成するだけだからです…。

確かに、それは非常に良い質問です。参考データとして、キャッシュのみに対して実行されるため、この LINQ クエリでは、LINQ クエリを実行している製品と属性にインデックスが付けられている必要があります。実際、私はそうしていますインデックス データを使用すると、インデックス付けが非常に簡単になります。タイプとモデルを指定して、インデックス付けする必要がある属性を指定するだけです。 したがって、これらはインデックス属性であり、実際にインデックス属性に対してクエリを実行しています。 それがあなたの質問の答えになることを願っています。

キャッシュを最新に保つ

すぐに実践部分に移り、実際に動作する製品を示してから、このウェビナーの最も重要な部分を説明します。データベースと比較して、また参照データに関してキャッシュ データを最新に保つ方法について説明します。トランザクションデータ。

さて、新しいプロジェクトを開きます。 さて、それでは、実践的なデモ部分です。分散キャッシュがどのようなものかを知っていただくために、実際の製品が動作している様子をすぐに示します。次に、それに対してアプリケーションを実行し、それを維持する方法を説明します。それは新鮮であり、データとキャッシュも新鮮です。

すでにインストールしました NCache 私のボックス 107 と 108 の XNUMX つにあります。これらをキャッシュ サーバーと個人用マシンとして使用するつもりです。私のラップトップはクライアントとして機能します。

そこで、まず最初に起動します。 NCache インストールされているマネージャーツール NCache キャッシュを作成します。たとえば、EF Core キャッシュという名前を付けます。 サーバーを 1 台使用します。 パーティション レプリカをキャッシュ トポロジとして保持し、非同期レプリケーション オプションを使用します。これは、その方が高速であるためです。ここでは、キャッシュをホストするサーバーを指定しました。 したがって、デモ 2 とデモ XNUMX の XNUMX つのサーバーと通信用の TCP/IP ポートがあります。 サーバーとクライアント間の通信に関する限り、すべて TCP/IP によって駆動されます。

キャッシュする予定のデータに基づくキャッシュのサイズ。 参照データの場合は、すべての製品、すべての顧客をロードしていることを考慮する必要があります。 同様に、トランザクション データの場合は、ワーキング セットとそれに対する追加の余地も考慮する必要があります。 すべてをシンプルにして、「終了」を選択すれば完了です。 始めるのはとても簡単です NCache そしてキャッシュを設定します。

私は自分のマシン上でアプリケーションを実行しているので、自分のボックスをクライアント マシンとして追加するだけで済みます。 このキャッシュ クラスターを起動してテストできます。その後、サンプル アプリケーションを実行してそれに接続します。 それはとても簡単です。 定期的に開催しております NCache アーキテクチャと .NET アプリのスケーリングに関するウェビナーでは、これらの構成について詳しく説明します。 したがって、質問がある場合は、これらのウェビナーも参照してください。

モニタリングの側面についてもいくつか紹介します。 統計ウィンドウを開きます NCache モニタリング ツールを使用すると、インストールされているストレス テスト ツール アプリケーションを実際に実行できるようになります。 NCache そして物事が実際に動いているのを見てください。 つまり、これはストレステストツールです。 私のボックスはクライアントなので、これに対して実行します。名前を指定するだけでこれに接続でき、キャッシュ クラスターでダミーの負荷をシミュレートできるはずです。 キャッシュ サイズは増加しており、アイテムは追加されており、XNUMX 秒あたりのリクエストの負荷も両方のサーバーでのアクティビティを示しています。その後、この監視ツールではダッシュボードの作成に時間がかかっていると思います。

ストレステストツール

それで、それを実行して、その間にサーバー自体からこのツールの別のインスタンスを実行させてください。 悪いです。 わかりました。XNUMX 秒あたりのリクエスト量が増加していることがわかります。 何らかの理由で、監視ツールであるダッシュボードの読み込みに時間がかかります。 このツールが戻ってきたらすぐにここに残しておこうと思います。このツールの監視の詳細をお見せします。

キャッシュを最新の状態に保つ: 参照データ

このウェビナーの次のセグメントでは、Entity Framework Core アプリケーション内でキャッシュ データを最新の状態に保ちます。このために、参照データとトランザクション データの例を再度使用します。 それでは、参考データから始めます。

キャッシュの最新の参照データを保持する

参照データをキャッシュするには、データセット全体をキャッシュにキャッシュする必要があることはすでに確立しています。 たとえば、製品がある場合、すべての製品をキャッシュにロードしてから、それらを個別のエンティティとしてロードする必要があります。 では、これの何が問題なのでしょうか?

参照データなので、参照データ全体をキャッシュに保存し、FromCacheOnly 拡張メソッドを使用してキャッシュのみを使用します。 ここで、部分的なデータセットをキャッシュから取り出すことは望ましくありません。 製造中止された製品である場合、またはいくつかの条件を実行している場合は、それらすべての製品をキャッシュに含める必要があります。 ただし、これらの製品がデータベース内で実際に変更される可能性があります。 現在、データは XNUMX つの異なる場所に存在しています。 マスターコピーであるデータベースがあり、データ全体をキャッシュにロードしましたが、アプリケーションの範囲外でデータベースが更新される可能性があります。

したがって、キャッシュ データを最新の状態に保つには、データとキャッシュを自動的に更新する何らかのメカニズムを確保する必要があります。そのためには XNUMX つのオプションがあります。 オプション XNUMX つは、有効期限を使用することです。

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddHours(10)); 	
    options.SetResyncProviderName("MyEFCoreResyncProvider");
	
	// Load all products into cache with Expiration and Auto-Reload
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

これは時間ベースの有効期限であり、自動リロード機能と組み合わせて使用​​します。 NCache 有効期限機能を使用すると、指定した期間 (たとえば、5 時間、10 時間) が経過した後にデータを期限切れにし、データを削除できます。また、参照データの場合、これは長期にわたる実行データであるため、参照データ、マスター データであるため、変更の頻度は高くありません。それは素晴らしいことなので、5 時間、10 時間、24 時間など、快適な数を思いつくことができます。 したがって、それに基づいて有効期限を設定できます。 ただし、前述したように、そのデータを失ったり、キャッシュから削除したりすることは実際には望ましくありません。

本当に必要なのは、変更されるデータ、たとえば 10 個の製品が、指定した有効期限に基づいて期限切れになることです。自動リロード メカニズムを使用して、そのデータをキャッシュに自動的にリロードする必要があります。 そして NCache は、リードスルー ハンドラーの助けを借りてそれを提供します。 したがって、必要なのは、キャッシュへのロードを使用してデータ全体とキャッシュを再度ロードし、個別のエンティティを使用しますが、同時にこれらの特性を使用することだけです。 絶対有効期限の設定など。

これは、キャッシュにロードされるすべての製品に設定する有効期限値であり、その後、再同期プロバイダーを設定します。これにより、基本的に、内部でリードスルー プロバイダーが呼び出されます。 NCache。 リードスルーは有効期限と組み合わされます。 したがって、キャッシュからデータを削除するのではなく、実際に再ロードします。キャッシュはすべてのキーとすべてのデータベース関連情報を知っているため、コンテキストを渡すだけで済みます。そのコンテキストに基づいて、実際にプロバイダーを自動呼び出しして再同期します。 データ ソースから更新された値を取得します。

その実際の例を示しましょう。 ここに方法があります。 これを別のエンティティとして保存しています。 通常、有効期限を 5 時間に設定しますが、それほど時間がないので、実際に行うのは、約 30 秒の有効期限を設定し、ここにブレークポイントを置き、すべてのファイルをロードします。製品をキャッシュに追加します。 この時点では、有効期限がどのように機能するかを示すためだけに再同期プロバイダーを設定するつもりはありません。有効期限が切れるとすぐにアイテムがキャッシュから削除されます。その後、このシナリオに対処する方法を示します。削除する代わりに、リードスルー ハンドラーを使用してリロードするだけです。

したがって、このサンプル ビットにはローカル キャッシュを使用します。 念のため内容をクリアしてから、このコードを実行してブレークポイントに到達します。 右。 で、有効期限が30秒あるので、打てば廃盤商品が手に入りますね。 ここにはすべての製品があり、約 30 のエントリがあります。 0 秒後、これらの XNUMX 個のアイテムは、この絶対有効期限に基づいて期限切れになります。設定したフラグを立てて、このクエリを再度実行すると、キャッシュに何も存在しないため、何も返されないことがわかります。 キャッシュからのみを使用しています。 そのため、期限切れの商品もございます。 これをもう一度実行すると、値が XNUMX になっていることがわかります。

したがって、これが参照データであり、データ全体がすでにキャッシュにロードされており、From Cache Only 拡張メソッドを呼び出していることを考慮すると、これは推奨されるものでも、推奨されるものでもありません。 したがって、部分的な応答や欠落したデータではなく、利用可能なすべてのデータが必須として必要であり、同時にこれは有効期限が切れた後に再ロードする必要があります。 削除する代わりに再ロードする必要があります。これはまさにこの Set Resync Provider 名の助けを借りて行うことです。

サンプルの再同期プロバイダーがここにあります。IReadThruProvider です。 実際には、これのデフォルト実装が提供されています。

namespace Alachisoft.NCache.EFSampleResyncProvider
{
    public abstract class EFDefaultResyncProvider : IReadThruProvider
    {
        public virtual void Init(IDictionary parameters, string cacheId)
        {
            db = InitializedDbContext();
        }
        public virtual void LoadFromSource(string key, out 					
        ProviderCacheItem cacheItem)
        {
            cacheItem = new ProviderCacheItem(FetchItemFromDb(key));
            cacheItem.AbsoluteExpiration = DateTime.Now.AddHours(10);
            cacheItem.ResyncItemOnExpiration = true;
        }
        public virtual void Dispose()
        {
            db.Dispose();
        }
    }
}

これは IReadThruProvider です。 あとは、設定したキャッシュを利用してこれを表示してみるだけです。 リードスルー ハンドラーを設定する必要があります。 たとえば、新しいキャッシュを作成してみましょう。ローカル キャッシュを作成してみましょう。 右。 つまり、それは単なるローカルキャッシュです。 バッキングソースをセットアップします。 リードスルーを有効にし、EF のデフォルトを追加してこれを設定する必要があります。これをプロジェクトとして使用でき、実装はすでに完了しています。

IReadThru ハンドラーを実装したような方法で機能します。 これはデフォルトの再同期プロバイダーです。 それにはいくつかの方法があります。 DB コンテキストを初期化する初期化があります。 有効期限が切れたときに呼び出される LoadFromSource で、この内部でデータベースから項目を取得しています。 定義の内部に入ると、実際にはすべてのデータベース関連の呼び出しが処理されます。これは実装の一部として提供されているものです。 NuGet パッケージはその一部としてこれをカバーしています。 したがって、キーを取得し、そのキーに基づいてコンテキストを渡し、そのコンテキストを使用して実際のオブジェクトをデータベースから直接取得します。

あなたがしなければならないことは、ご存知の通り、この EF Default Resync Provider を継承して実装し、独自の実装を提供してデータベース コンテキストを提供することだけです。

したがって、これは私たちが提供した抽象クラスです。 Northwind データベース コンテキストまたは手持ちのデータベース コンテキストを指定するだけでよく、それに基づいてこのメソッドがオーバーライド/実装されたら、これをキャッシュに登録するだけです。 たとえば、これは再同期プロバイダーです。 これを開けてみると、2つ入っていました。 XNUMX つはデフォルトで、もう XNUMX つは独自の実装であり、必要に応じて接続文字列やその他の情報を渡すことができます。それだけです。 これをデプロイするだけです。 この点について少しだけ説明しましょう。これで成功するでしょう。 したがって、それをしなければなりません。 先ほども述べたように、これはすでに一部として行われています NCache、 実装。 NuGet パッケージには再同期プロバイダーが付属しており、ここでこの特定のメソッドを実装し、コンテキストを提供することで簡単に実装できます。ジョブの残りの部分は、実際には拡張機能と同じ行で動作するこのサンプルのデフォルト再同期プロバイダーによって実行されます。メソッドは機能します。

キーを構築することで、どのキーがどのエンティティを表すかを把握し、そのエンティティとそのキー情報に基づいて、Entity Framework の API を使用して実際にデータベースにクエリを実行します。 これは私のキャッシュに対してすでに行われています。 ここで私がやったことは、私が持っているもので、正常にデプロイされました。 したがって、キャッシュについてはすでにこれを行っています。 この EF のデフォルトがあり、それをデプロイしました。 そこで、同じユースケースを実行しますが、今回は単に期限切れにするのではなく、実際にリロードします。 それで、それが私がやることです。 私がしなければならないのは、再同期プロバイダー名を設定することだけです。その後、いくつかの値も更新する予定なので、60 秒を使用します。 通常、参照データの場合は、絶対有効期限として 5 時間以上など、さらに長い時間を指定します。 したがって、60 秒で実行すると、今度は再同期プロバイダーが設定されていることがわかります。

そこで、このユースケースをもう一度実行して、これが削除ではなく有効期限切れではなく更新される方法を示します。 それで、これは実行されました、そしてできればこの時点に戻ってくることを願っています。 大丈夫。 これで、製品がロードされました。 これをもう一度実行します。今回は有効期限が 60 秒あるため、この特定の製品、製品 ID を更新します。 17 それで、私たちがやることは、それを更新するということだけです、わかりました。

データベース内では更新されますが、キャッシュ データのみを使用しており、まだ有効期限が切れていないため、アプリケーション コンテキストではまだ更新されません。 したがって、古い値を取得し続けます。キャッシュに数千のアイテムがあり、60 秒あたりのリードスルーがあることに気付いた場合、XNUMX 秒後に何らかのアクティビティが表示され、その後、用意されているリードスルー ハンドラーが自動的に呼び出されます。セットアップするだけです。

それで、もう一度実行してみましょう。まだリロードされていない場合は、注文値が再び期待されますが、リロードされる時点があり、その後、期限切れになるのではなく、単純に999個がリロードされます。プロダクト。 追加の項目が 1000 つあります。通常は参照です。 さあ、どうぞ。 つまり、有効期限ではなく、1000 つの項目だけが期限切れになりました。これはキーのリストであるためです。そうでない場合は、クエリに基づくすべての参照データです。クエリを見せてください。製品 ID が XNUMX 未満であることが示されています。つまり、実際には、は XNUMX 製品を表します。

そこで、このクエリをもう一度実行します。今回は、データが削除ではなく期限切れ時にすでに更新されているためです。 したがって、更新された製品がキャッシュに追加されることを期待しています。 それでは、どうぞ。 したがって、この一環として私の製品も更新されました。 したがって、これは、有効期限を使用するが自動リロード機能を使用するというオプション 24 の一部として推奨するものです。 したがって、期限切れにする代わりに、単にデータをリロードするだけで、キャッシュ データを最新の状態に保つことができます。 したがって、データをキャッシュに保持できる快適な時間を考え出します。古いデータが取得され続け、その古いデータの有効期限が切れるとすぐに、2 日相当の時間 (たとえば XNUMX 時間) がかかる可能性があります。 、XNUMX 日、XNUMX 週間など、アプリケーション内で都合のよい時間に設定できます。 数時間かかる場合もありますが、その後はキャッシュ内のデータがリロードされるだけです。

したがって、それが私たちの選択肢の XNUMX つ目です。 かなり簡単だったと思います。

オプション XNUMX は、有効期限を使用しないことです。 したがって、データが常にキャッシュ内に存在するこの問題は、これで解決されます。 ただし、キャッシュ内のデータが古くなっている可能性があり、永久に古いままになる可能性があります。 そのためには手動でリロードする必要がありますが、これも非常に簡単です。

void LoadAllProducts (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities,
	};
		
	var res = (from products in database.Products select
    products).LoadIntoCache(options).ToList();

}

定期的にこの Load All Products を呼び出すだけです。 たとえば、ここでこの点に戻ってみましょう。 したがって、このメソッドは一定の間隔を置いて呼び出す必要があります。また、前述したように、これは通常アプリケーションの起動時に実行され、それを担当しているアプリケーションの 5 つがこれらすべてを処理している可能性があります。 したがって、それは、アプリケーションの 24 つである可能性もあれば、それを実行している別のアプリケーションである可能性もあります。 したがって、それはあなたのアプリケーションである可能性があり、あなたのアプリケーションインスタンスのXNUMXつであるか、または完全に別のアプリケーションである可能性があり、そのアプリケーションは、たとえばXNUMX時間後、XNUMX時間後など、あなたが望む快適な時間の後に定期的にこのメソッドを呼び出すことができます。これをデータベースに対して実行し、製品をリロードしたいとします。

したがって、LoadIntoCache は、データベースに対して実行し、新しいコピーをキャッシュにロードするという特定のシナリオを処理します。 それが参照データを担当する方法です。 かなり率直だったと思います。

キャッシュを最新の状態に保つ: トランザクション データ

トランザクション データを使用する次のセグメントに進みましょう。 さて、トランザクション データは存続期間が短いものです。 前に説明したように、これはワーキング セットです。 したがって、5 ~ 10 分の有効期限を使用してもよいでしょう。 それで、ここで実際に何をする必要があるかというと、キャッシュに対して実行する FromCache を使用しているため、それがキャッシュに存在する場合、およびキャッシュに存在しない場合には、常にデータベースに対して自動的に実行されます。 したがって、これは、キャッシュに対してのみ実行される参照データ シナリオで使用する FromCacheOnly とは異なり、この拡張メソッドに組み込まれています。 したがって、コレクションとして保存した場合でも、別個のエンティティとして保存した場合でも、一部のデータが利用可能であっても問題ありません。

有効期限が短く、自動リロードなし
 private List<Orders> GetCustomerOrders (string CustomerID)
{
	CachingOptions options = new CachingOptions	
	{
		StoreAs = StoreAs = StoreAs.Collection
	};
	
	options.SetAbsoluteExpiration(DateTime.Now.AddSeconds(60));

    	List<Orders> orderList = (from customerOrder in database.Orders 					
        where customerOrder.Customer.CustomerId==CustomerID 
        select customerOrder).FromCache(out string cacheKey,
        options).ToList();

	return orderList;
 }

したがって、単純に短い有効期限 (たとえば 60 秒) を使用します。ただし、この例は参照データに使用しましたが、これはこの特定のデモのためでした。ただし、参照データの有効期限は通常 5 ~ 10 時間で、トランザクション データの有効期限は通常 60 ~ XNUMX 時間です。 XNUMX 秒間のどこかに、有効期限が関連付けられています。From Cache を使用しているので、実際に Get Customer Orders を見てみましょう。FromCache を使用しているので、これを使用できるようにする必要があります。実際にこれを次のように考えてみましょう。例。

そうですね、ここで有効期限を設定し、この FromCache 拡張メソッドを呼び出します。これにより、キャッシュに存在しない場合、およびしばらくしてから作業セットがアクティブになっているかどうかをデータベースから取得する必要があります。キャッシュはキャッシュから取得しますが、キャッシュ内でアクティブでない場合は、もう必要ない可能性があります。 したがって、最終的にはデータベースに戻ることになるかもしれませんが、それがトランザクション データを扱う正しい方法です。 したがって、この記事で参照データとトランザクション データのシナリオ、およびこれら XNUMX つに関してキャッシュ データを最新の状態に保つ方法について説明できれば幸いです。

キャッシュ内の関係の処理

次のセグメントであるキャッシュ内の関係の処理に進みます。

ロン、ここでいくつか質問があります。 しますか? NCache それともキャッシュされたアイテムは NCache それとも各アプリケーションサーバーでシャドウされていますか?

彼らが住んでいるのは、 NCache。 そうです、アイテムは実際に存在します NCache、 右。 したがって、実際のリポジトリは NCache そして実際にこれらのエンティティ メソッドと一緒にキーとオブジェクトを構築します。 それで、それがここでのアイデアです。

もう XNUMX つの質問は、参照データをキャッシュに追加するときに、複数のキャッシュ ローダーを構成できるか、それともすべてを XNUMX つに構成する必要があるかということです。

キャッシュへのロードは一般的な方法なので、それが可能です。 したがって、実際には、実行しようとしているクエリであれば何でもロードされます。 したがって、クエリにバインドされます。 キャッシュに複数のロードを含めることができ、XNUMX つの別個のアプリケーションまたはアプリケーション内の異なる場所にロードすることができます。 したがって、その点でも非常に柔軟です。

キャッシュ内の関係の処理: XNUMX 対多

List<Region> GetRegionWithTerritories(NorthwindContext database)
{
	List<Region> regionDetails;
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.SeperateEntities
	};

	regionDetails = (from region in database.Region select region)
					.Include(region => region.Territories)
					.FromCache(options).ToList();

	return regionDetails;
}

強調したい重要な概念がいくつかあります。 人間関係にどう対処するか? XNUMX 対多と多対多の例です。

XNUMX対多に焦点を当てましょう。 たとえば、リージョンがあり、リージョンの一部であるテリトリーがあり、リージョンとテリトリーの間には XNUMX 対多の関係が生じます。 同期アプローチに進み、実際にここからリージョンを取得しましょう。

さて、それでは、領土のあるリージョンを取得します。 ここでの基本的な考え方は、Include キーワードがあり、FromCache を使用し、それを常に別のエンティティとして保存するということです。 ここでの考え方は、リージョンの親アイテムが別のアイテムとしてキャッシュに保存されるということです。 リージョンはテリトリーと XNUMX 対多の関係もあり、各リージョン エンティティ内にはテリトリーのコレクションが存在するため、 NCache それに従うだろう。 FromCache を呼び出すとすぐに、単にリージョンが取得され、すべてのリージョンが別個のエンティティとして保存され、指定したスコープに基づいて、FromCache の助けを借りてすべてのテリトリーが各リージョン内の別個のコレクションとして保存されます。 。

したがって、これは、関連オブジェクトとしてのコレクションの側面という、多くの側面を持つ XNUMX つのエンティティです。 これが、XNUMX 対多のユースケースに取り組む方法です。

集計操作のキャッシュ

次に、キャッシュ集計操作があります。 ご存知のとおり、結果をエンティティにすることも、結果を値にすることもできます。

キャッシュ集約操作

たとえば、最初の配送業者またはデフォルトの配送業者を取得します。 つまり、ここで First または Default を実行すると、最初の配送者が取得され、これに基づいてこれが保存されることがわかります。 NCache.

同様に、カウント合計の場合もあります。 これは任意の集計操作である可能性があるため、値である可能性があります。 繰り返しますが、これは次の場所に保存できます NCache 別個の存在として。

Shippers GetFirstShipperInstance (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{ 
		StoreAs = StoreAs.Collection
	};

	Shippers shipper = database.Shippers.DeferredFirstOrDefault()
						.FromCache(out string cacheKey, options);

	return shipper;

}

同様に、カウント合計の場合もあります。 これは任意の集計操作である可能性があるため、値である可能性があります。 繰り返しますが、これは次の場所に保存できます。 NCache 別個の存在として。

int GetTotalShippersCount (NorthwindContext database)
{
	CachingOptions options = new CachingOptions
	{
		StoreAs = StoreAs.Collection 
	};

	int count = database.Shippers.DeferredCount()
				.FromCache(out 	string cacheKey, options);
	
	return count;

}

分散キャッシュアーキテクチャ

したがって、これは技術的な部分に関する限りのウェビナーをカバーしています。 最後に、分散キャッシュ アーキテクチャをいくつか紹介します。

高可用性

NCache 製品は非常にスケーラブルで高速であるためです。 これは、プロトコルのピアツーピア アーキテクチャに基づいたものです。 単一障害点はありません。 実行中のキャッシュに対してオンザフライでサーバーを追加または削除できます。 キャッシュやそれに接続されているクライアントを停止する必要はありません。 したがって、実行中のキャッシュ クラスターに動的に変更を加えることができます。

高可用性

キャッシングトポロジ

最も人気のあるトポロジは次のとおりです。 パーティションレプリカキャッシュ。 これにより、すべてのサーバーにパーティションの形式でデータを簡単に分散できます。 つまり、メモリ リソースと計算リソースをプールし、論理容量を提供し、各サーバーにはバックアップも用意されています。 Server1 は 2 のバックアップです。Serve2 は 1 のバックアップであり、Serve3 は Serve1 のバックアップです。 したがって、ラウンドロビン方式で、各サーバーは別のサーバーにバックアップを作成します。

キャッシュトポロジ

クライアントキャッシュ(キャッシュの近く)

同様に、これは非常に高速で、拡張性が高く、最も人気のあるトポロジです。 また、 クライアントキャッシュ 独自のアプリケーションボックスで実行できます。 これはローカル キャッシュですが、サーバー キャッシュと同期されています。 コードを変更することなく、データのサブセットが自動的にキャッシュに取り込まれます。 これにより、データのほとんどが参照に関するものである場合、パフォーマンスが向上します。 したがって、キャッシュにロードしてから、FromCacheOnly クライアント キャッシュを呼び出してこのデータのサブセットの呼び出しを開始すると、その場合に非常に役立ちます。

クライアントキャッシュ

キャッシュのWANレプリケーション

WANレプリケーション もう XNUMX つの機能であるブリッジ レプリケーションです。 アクティブ/パッシブまたはアクティブ/アクティブ データ サイトを使用できます。 すべてのデータ、EF Core データ、ASP.NET セッション、または通常のデータは、アクティブ/パッシブまたはアクティブ/アクティブ方式で WAN 経由でターゲット サイトに転送できます。 それで、これが何ですか NCache その一部としてカバーします。

wan-レプリケーション

まとめ

繰り返しになりますが、ニックに渡す前にもう XNUMX 分かかります。 そこで、単一のエンティティと、直接 API を使用したエンティティ コレクションの保存について説明しました。 それは拡張メソッドの点で少し異なり、その後、本質的に非常に単純で、本質的により柔軟な拡張メソッドについて話しました。 FromCache は、キャッシュが存在する場合はキャッシュから何かを取得し、存在しない場合はデータ ソースから自動的に取得する最初のメソッドであり、自分で実装する必要がある直接 API とは異なります。 また、ここで設定するキーと関連オプションも構築します。

次に、参照データとトランザクション データについて話しました。 参照データを処理するには、LoadIntoCache を使用してデータ全体をロードする必要があり、FromCacheOnly を呼び出す必要があります。 LoadIntoCache は常にデータベースに対して実行されますが、FromCacheOnly はキャッシュに対してのみ実行されます。次に、FromCache を使用して処理できるトランザクション データについて説明し、いくつかの有効期限を設定します。 参照データを最新の状態に保つには、有効期限を設定してから自動リロードを使用するか、有効期限を使用せずに LoadIntoCache を使用して手動でリロードする必要があります。 次に、トランザクション データについて話しました。これは、ある種の有効期限を考え出し、キャッシュ内に存在する場合は取得できるように FromCache を使用する必要があります。 キャッシュに存在しない場合は、常にデータベースから取得します。

以上でプレゼンテーションを終わります。 ご質問がございましたらお知らせください。

いつでもご連絡いただけます。 support@alachisoft.com。 技術的な質問がある場合は、次の方法でもお問い合わせいただけます。 sales@alachisoft.com。 実際に見てみたい場合は、製品をダウンロードして、当社の Web サイトにアクセスしてください。 alachisoft.comからダウンロードできます NCache 30 日間使用できる試用版が付属しています。ご不明な点がございましたら、お知らせください。そうでない場合は、本日はこのショーとウェビナーにご参加いただき、誠にありがとうございます。また次回お会いしましょう。 ロンさん、本当にありがとうございました。 君たちありがとう。

次はどうする?

 

お問い合わせ(英語)

電話
©著作権 Alachisoft 2002 - . All rights reserved. NCache はダイヤテック株式会社の登録商標です。