この記事では、分散キャッシュ ソリューションがマイクロサービス ベースのアプリケーションの全体的なパフォーマンスとスループットを大幅に向上させる方法について説明します。
典型的なマイクロサービス ベースのアプリケーションでは、疎結合とスケーラビリティを維持しながら、複数のマイクロサービスが連携して動作します。 アプリケーションには、重要なビジネス データの追跡や処理など、コア ビジネス要件を満たすために必要なサービスがあります。 ID と認証、正常性と負荷の監視を処理し、API ゲートウェイとして機能する追加の専用マイクロサービスもあります。
このようなアプリケーションの重要な機能は、必要なテクノロジ スタックを使用して、各マイクロサービスを個別に設計、開発、デプロイできることです。 各マイクロサービスはそれ自体がスタンドアロンの自律型アプリであるため、リレーショナル データベースや NoSQL DB または従来のファイル ストレージ システムですらあります。 これにより、個々のマイクロサービスを個別にスケーリングできるようになり、リアルタイムのインフラストラクチャの変更がはるかに管理しやすくなります。
NCache 詳細 とのマイクロサービス NCache マイクロサービスでのPub/Subのスケーリング
マイクロサービスが必要な理由 NCache?
アプリケーションでのトランザクションが増加すると、依然としてボトルネックが発生する場合があります。 これは、マイクロサービスがスケールアウトを許可しないリレーショナル データベースにデータを格納するアーキテクチャで主に一般的です。 このような状況では、より多くのインスタンスをデプロイしてマイクロサービスをスケールアウトしても、問題は解決しません。
これらの問題に対処するために、シームレスに導入できます NCache マイクロサービスとデータストアの間のキャッシング レイヤーでの分散キャッシュとして。 NCache また、メモリ内のスケーラブルなパブリッシャー/サブスクライバー メッセージング ブローカーとしても役立ち、マイクロサービス間の非同期通信を可能にします。
Pub/Sub によるスケーラビリティ
マイクロサービス通信は、マイクロサービス間のメッセージングを可能にするパブリッシャー/サブスクライバーモデルを使用して頻繁に実装されますが、マイクロサービスは緩く結合されたままです。 その点で、 NCache アプリケーションを構成するすべてのマイクロサービスがイベントをパブリッシュおよびサブスクライブできる、メモリ内のスケーラブルなPub/Subメッセージングブローカーとして機能します。 に固有のスケーラビリティと信頼性の機能 NCache pub / subになると、クラスタリングは自動的に変換されます。 詳細をご覧ください NCache マイクロサービス環境のメッセージブローカーとして、 インメモリPub/Subを使用した.NETマイクロサービス通信のスケーリング.
NCache 詳細 でのPub/Subメッセージング NCache マイクロサービスでのPub/Subのスケーリング
キャッシングによるスケーラビリティ
NCache リアルタイムのスケーラビリティを提供し、アプリケーションのダウンタイムを発生させることなく、実行中のキャッシュ クラスターに必要な数のサーバー ノードを追加できます。 使用する NCache 高速なメモリ内ストアとして機能することで個々のマイクロサービスの全体的なパフォーマンスを向上させるだけでなく、クラスタリング アーキテクチャによってアプリケーションの応答時間と可用性を大幅に向上させます。 これは、複数のホストにまたがる数十のマイクロサービスを含むワークフローを検討する場合に特に当てはまります。
使い方 NCache データキャッシング用?
NCache マイクロサービスがデータを必要とする場合、毎回データベースに直接アクセスするのではなく、最初にキャッシュをチェックします。 通常、最も頻繁にアクセスされるデータは、データストアで使用可能なデータ全体のごく一部を占めているため、そのデータを既にキャッシュして使用できるようにしておくと、データベース関連のレイテンシが大幅に削減されるだけでなく、データベースの負荷が軽減されます。のデータ要求は、キャッシュ自体によって処理されます。
モノリシックな設計構造を使用して構築された場合よりも、マイクロサービス ベースのアプリケーションが本質的に遅いことを考えると、 NCache. NCacheをマイクロサービス レベルで使用すると、マイクロサービス アーキテクチャの機能を活用しながら、連続して動作する複数のサービスにまたがる長いトランザクション中に観察される全体的なレイテンシを大幅に削減できます。
NCache には、キャッシュ操作をきめ細かく制御できる、すぐに使用できる機能がいくつかあります。 これらの操作には、有効期限とデータベース同期を使用したキャッシュの一貫性の強制、バッキング ソース プロバイダーを使用したキャッシュ アサイド機能とキャッシュ スルー機能の実装に役立つ豊富な API が含まれます。 NCache また、SQL クエリを使用してキャッシュ上で SQL に似たクエリ操作を提供するだけでなく、EF Core などのオブジェクト リレーショナル マッパー (ORM) のキャッシュ プロバイダーとしても機能します。
始めるには NCache マイクロサービス ベースのアプリケーションでは、最初にサービスを構成する必要があります。 これにより、マイクロサービスが使用を開始するために必要な情報が提供されます NCache. 間の相互コンテキストを作成する方法の概要 NCache マイクロサービスベースのアプリケーションを以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public IServiceProvider ConfigureServices(IServiceCollection services) { //Add additional code here services.AddDbContext<CatalogContext>(options => { var cacheID = configuration["CatalogCache"]; if (string.IsNullOrEmpty(cacheID)) cacheID = "CatalogCache"; NCacheConfiguration.Configure(cacheID, DependencyType.Other); // Changing default behavior when client evaluation occurs to throw. // Default in EF Core would be to log a warning when client evaluation is performed. options.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval }); var container = new ContainerBuilder(); container.Populate(services); return new AutofacServiceProvider(container.Build()); } |
ここで行う必要があるのは、キャッシュ内でアイテムが見つかった場合にキャッシュからアイテムを取得できるようにするロジックを備えたコントローラーをデプロイすることです。 そうでない場合、コントローラーはデータベースからアイテムを取得し、キャッシュに保存します。 このようなコントローラーの実装を以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
[Route("api/v1/[controller]")] [ApiController] public class CatalogController : ControllerBase { private readonly CatalogContext _catalogContext; private readonly CatalogSettings _settings; private readonly ICatalogIntegrationEventService _catalogIntegrationEventService; public CatalogController(CatalogContext context, IOptionsSnapshot<CatalogSettings> settings, ICatalogIntegrationEventService catalogIntegrationEventService) { _catalogContext = context ?? throw new ArgumentNullException(nameof(context)); _catalogIntegrationEventService = catalogIntegrationEventService ?? throw new ArgumentNullException(nameof(catalogIntegrationEventService)); _settings = settings.Value; } [HttpGet] [Route("items/{id:int}")] [ProducesResponseType((int)HttpStatusCode.NotFound)] [ProducesResponseType((int)HttpStatusCode.BadRequest)] [ProducesResponseType(typeof(CatalogItem), (int)HttpStatusCode.OK)] public async Task<ActionResult<CatalogItem>> ItemByIdAsync(int id) { if (id <= 0) { return BadRequest(); } CatalogItem item = null; var cache = _catalogContext.GetCache(); string catalogItemKey = "CatalogItem:" + id; //Getting item from cache item = cache.Get<CatalogItem>(catalogItemKey); if (item == null) { item = await _catalogContext.CatalogItems.SingleOrDefaultAsync(ci => ci.Id == id); cache.Insert(catalogItemKey, item); } // Your logic here if (item != null) return item; return NotFound(); } } |
その魅力に迫るべく、その詳細をご紹介しましょう。 NCache マイクロサービスで。
キャッシュを常に最新の状態に保つ
基盤となるプライマリデータストアのコンテンツと比較した場合、「古い」データを保持するキャッシュに関連するキャッシュを使用する場合は、重要な注意事項があります。 特定のマイクロサービスがキャッシュから新しいデータを確実に受信するには、キャッシュデータを定期的に更新する必要があります。 幸運にも、 NCache 次のような機能を提供します データベースの同期 & 満了 データがプライマリデータストアのデータと一貫性を保つようにするため。
キャッシュされたアイテムに有効期限の時間間隔を追加するだけで、キャッシュとデータストアの同期レベルを維持できます。 期限切れになると、 NCache キャッシュされたアイテムを削除して、同じ情報に対する後続の要求により、更新されたデータがキャッシュされるようにします。 NCache 両方を提供します 絶対の と同様 スライディング 有効期限戦略と、問題のデータの一時的な性質に応じてどちらかを使用できます。
例として、次のコード スニペットは、特定のキャッシュ アイテムに絶対有効期限を簡単に導入できることを示しています。
1 2 3 4 |
var cacheItem = new CacheItem(product); var expiration = new Expiration(ExpirationType.Absolute, TimeSpan.FromMinutes(5)); cacheItem.Expiration = expiration; cache.Insert(key, cacheItem); |
スライド有効期限を使用するには、ExpirationType を次のように変更するだけです。
1 |
var expiration = new Expiration(ExpirationType.Sliding, TimeSpan.FromMinutes(5)); |
キャッシュ データの整合性を維持するために任意のキャッシュに有効期限を設定する際の主な要件は、データ ストア側で特定のデータがどれだけ速く変化するかに応じて有効期限を設定する必要があることです。 有効期限の設定が短すぎると、データが不必要に削除される可能性があり、不必要でコストのかかるデータストアへのトリップが発生します。 有効期限が長すぎると、古いデータが使用される可能性があります。
したがって、有効期限の最適値を見つけるには、データ状態の変化パターンに関する深い知識が必要ですが、これは通常は実現不可能です。 キャッシュの一貫性の要件がより厳しくなった場合は、データベース同期戦略が推奨されるアプローチです。 NCache この点に関して、いくつかのデータベース同期戦略を提供します。
これらを使用すると、有効期限を使用するときに必要な各情報のデータ アクセス パターンに入る必要なく、キャッシュをデータストアと同期できます。 これで、データストア側でその項目に変更があった場合はいつでも、キャッシュはその項目をさらに遅延することなく自動的に削除できます。
これが実際に動作することを確認するために、次のコードスニペットは同期する方法を示しています NCache SQLServerデータベースを追加して NCache SQLの依存関係 キャッシュされたアイテム。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Creating SQL Dependency string query = "SELECT ProductName, UnitPrice FROM dbo.Products WHERE CategoryID = 'Dairy';"; SqlCacheDependency sqlDependency = new SqlCacheDependency(connectionString, query); // Get orders that contain products with given category ID Order[] orders = FetchOrdersByProductCategoryID("Dairy"); foreach (var order in orders) { // Generate a unique cache key for this order string key = $"Order:ProductCategory-Dairy:{order.OrderID}"; // Create a new cacheitem and add sql dependency to it CacheItem item = new CacheItem(order); item.Dependency = sqlDependency; //Add cache item in the cache with SQL Dependency cache.Insert(key, item); } |
キャッシュ上の SQL クエリ
NCache SQL に似たクエリ メカニズムを使用して、インデックス付きキャッシュ データをクエリする機能をマイクロサービスに提供します。 この機能は、必要な情報が保存されているキーの値が不明な場合に役立ちます。 これにより、低レベルのキャッシュ API 呼び出しの多くが抽象化され、アプリケーション コードの理解と維持がかなり容易になります。 この機能は、SQL に似たコマンドに慣れている場合に特に適していることがわかります。
の使用を示すコード スニペットの例 NCache SQL クエリ機能を以下に示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
string query = "SELECT * FROM FQN.Product WHERE ProductID > ?"; // Use QueryCommand for query execution var queryCommand = new QueryCommand(query); // Providing parameters for query queryCommand.Parameters.Add("ProductID",50000); // Executing QueryCommand through ICacheReader ICacheReader reader = cache.SearchService.ExecuteReader(queryCommand); // Check if the result set is not empty if (reader.FieldCount > 0) { while (reader.Read()) { string result = reader.GetValue<string>(1); // Perform operations using the retrieved keys } } else { // Null query result set retrieved } |
SQL クエリは、クエリ インデックスを使用できます。 NCache 分散データ構造とキャッシュタグ。 詳細については、リンクをたどってください 使い方 NCache SQL クエリ機能.
読み取りスルーと書き込みスルー
使い方 NCache データソースプロバイダー 機能、セット NCache マイクロサービスの観点から、データアクセス層への単一のエントリとしてアップ。 マイクロサービスがデータを必要とする場合、キャッシュにアクセスするだけで済みます。 キャッシュは、データがキャッシュで使用可能な場合はデータを提供しますが、使用できない場合は、先に進み、クライアントに代わってリードスルーハンドラーを使用してデータストアからデータを取得し、キャッシュしてマイクロサービスに提示します。
同様に、ライトスルー ハンドラーを利用することで、マイクロサービスはキャッシュに対して書き込み操作 (追加、更新、削除) を実行するだけで済み、キャッシュはデータストアに対して関連する書き込み操作を自動的に実行します。
さらに、古いバージョンの可能性のあるデータがキャッシュに保持されているかどうかに関係なく、キャッシュに強制的にデータ ストアから直接データを取得させることもできます。 これは、マイクロサービスが最新の情報を必要とし、前述のキャッシュの一貫性戦略に基づいている場合に重要です。
バッキング データ ソース プロバイダー機能は、アプリケーション コードを合理化するだけでなく、多くの機能と組み合わせて使用すると、 NCache データベース同期機能が利用可能で、計算の準備が整った自動リロードされた新しいデータでキャッシュが保持されます。
次のコード スニペットは、マイクロサービスでリードスルーの使用を開始するのに役立ちます。
1 2 3 4 5 6 |
// Specify the readThruOptions for read through operations var readThruOptions = new ReadThruOptions(); readThruOptions.Mode = ReadMode.ReadThru; // Retrieve the data of the corresponding item with reads thru enabled Product data = cache.Get<Product>(key, readThruOptions); |
同様に、以下を使用してライトスルーを実装できます。
1 2 3 4 5 6 |
// Enable write through for the cacheItem created var writeThruOptions = new WriteThruOptions(); writeThruOptions.Mode = WriteMode.WriteBehind; // Add item in the cache with write-behind cache.Insert(key, cacheItem, writeThruOptions); |
これらのプロバイダーの使用方法の詳細については、次のドキュメントを参照してください。 リードスルーキャッシング & ライトスルーキャッシング.
NCache 詳細 のデータソースプロバイダー NCache
EFコアキャッシング
Entity Framework(EF)コア は、エンタープライズ.NETアプリケーションで頻繁に使用される強力なオブジェクトリレーショナルマッパー(O / RM)です。 そしてそれはとても人気があるので、 NCache 提供 EFコアキャッシングプロバイダー これにより、FromCacheなどの拡張メソッドを使用して、EFCore関連のコード内にキャッシュをシームレスに追加できます。. これにより、EFCore開発者は精通していない可能性があります NCache の力を引き続き利用するためのAPI NCache.
次のコードは、 NCache 既存のマイクロサービス アプリケーション ロジックにキャッシュを導入するための EF Core キャッシュ プロバイダー。
1 2 3 4 5 6 7 8 9 |
var options = new CachingOptions { // To store the result as collection in cache StoreAs = StoreAs.Collection }; options.SetAbsoluteExpiration(DateTime.Now.AddMinutes(_settings.NCacheAbsoluteExpirationTime)); // Get items from cache. If not found, fetch from database and store in cache. item = await _catalogContext.CatalogItems.DeferredSingleOrDefault(ci => ci.Id == id).FromCacheAsync(options); |
EF Core Caching Provider APIの詳細と、それがビジネスケースにどのように役立つかについては、次のURLをご覧ください。 NCache EFコアプロバイダー.
それをすべてまとめます
マイクロサービスは、自律的であるべきという特定の意図を持って構築されています。 他のマイクロサービスとは独立して、それらを開発、テスト、デプロイできること。 これは、アプリケーション全体を高度にスケーラブルにするだけでなく、高速の継続的インテグレーション/継続的デプロイメント(CI / CD)プロセスに対してオープンにするのに役立ちます。
ただし、スケーラビリティと迅速な開発ライフサイクルの点でマイクロサービスが提供するすべての利点に対して、ヒッチを引き起こすアプリケーション スタックの特定の側面があります。 これらの側面の中には、負荷の増加に対処するために必要なスケールアウトを許可しないリレーショナル データベースがあり、これは、 NCache 輝く。
NCache には、すぐに使用できる多数の機能があり、データ キャッシングを簡単かつ直感的にマイクロサービス アプリケーションに追加するのに役立ちます。 これらには、データベースの同期、有効期限、EF Core キャッシュ、SQL クエリ、および 一層.