.NET CoreとASP.NET Coreは、設計のシンプルさ、軽量性、オープンソースであること、そしてWindowsとLinuxの両方で動作することから、人気が高まっています。その結果、多くの既存アプリケーションも.NET Frameworkから.NET Coreに移行しています。現在、新規アプリケーションのほぼすべてが.NET Coreで開発されています。
これらの.NET Coreアプリケーションの多くは、数百万ものユーザーとトランザクションを処理する、トラフィック量の多いアプリケーションです。そのため、これらのアプリケーションはビジネスに大きな影響を与え、非常に重要な存在となります。
.NET Coreアプリケーションでスケーラビリティが求められるのは、通常、非常に高速な応答時間で大量のトランザクションを迅速に処理する必要のあるサーバーアプリケーションです。これらのアプリケーションの多くは顧客対応型であり、顧客からのリクエストを処理しています。顧客からのリクエストに迅速に対応できない場合、収益の損失や顧客離れといった形で、企業にとって大きな損失となります。
以下の.NET Coreアプリケーションにはスケーラビリティが求められます。
興味深いことに、上記のアプリケーションはすべて、非常にスケーラブルなアプリケーション レベルのアーキテクチャを備えています。 それぞれのサーバー、VM、またはコンテナー インスタンスとロード バランサーを追加することで、トランザクション負荷の増加に応じて線形に拡張できます。
しかし、アプリケーション層では非常にスケーラブルなアーキテクチャを採用しているにもかかわらず、今日の.NET Coreサーバーアプリケーションは、スケーラビリティの大きなボトルネックに直面しています。これらのボトルネックは、次のようなさまざまな領域で発生しています。
トラフィック量の多い.NET Coreアプリケーションにとって最大のボトルネックは、アプリケーションデータベースです。現在でも、ほとんどのアプリケーションはSQL ServerやOracleなどのリレーショナルデータベースを使用しています。これらのデータベースは、アプリケーションのトランザクション負荷が増加するにつれて、すぐにスケーラビリティのボトルネックとなります。これは、仮想マシン上でSQL Serverを使用している場合でも、Azure SQL Databaseを使用している場合でも同様です。
これは、リレーショナルデータベースはNoSQLデータベースのように論理的にパーティション分割することができず、物理的な場所に固定されるためです。列レベルのパーティション分割でさえ、真のNoSQLスタイルのパーティションとは全く異なります。したがって、NoSQLデータベースのようにデータベースサーバーを追加することでデータベース層のトランザクション処理能力を拡張することはできません。
たとえば、トランザクションの負荷が増加するにつれて、アプリケーション層には 10、20、30、またはそれ以上のアプリケーション サーバーが簡単に追加される可能性がありますが、データベース層は同じようにはまったく増加できません。
このため、リレーショナル データベースは、そこに保存するデータ (アプリケーション データまたはその他のデータ) のパフォーマンスのボトルネックになります。
SQL Server では、XNUMX 秒あたりのトランザクション数を増やすためにインメモリ最適化が導入されました。 Oracle は、独自のバージョンのインメモリ テーブルも提供しています。
インメモリの最適化はパフォーマンスの向上をもたらしますが、線形スケーラビリティという中核的な問題には対処しません。 インメモリ テーブルは通常、読み取り専用データに使用され、読み取り専用トランザクション容量を拡張するには、ハイエンド マシンに SQL Server のインスタンスを追加する必要があります。
インメモリ テーブルにはデータのサイズにも制限があります。 テーブル全体をメモリに配置する必要があるため、大きなテーブルをメモリに配置することはできません。 また、他の SQL Server インスタンスへのレプリケーションは、適切なデータベースではなく、他のインメモリ テーブルに対してのみ実行できます。
要約すると、SQL ServerやOracleデータベースにおけるこれらのインメモリ最適化は、.NET Coreアプリケーションのスケーラビリティに関するニーズに完全には対応できません。
NoSQLデータベースが普及した理由の一つは、ハッシュベースなどのアルゴリズムに基づいてデータを適切にパーティショニングできる点にある。これにより、SQL ServerやOracleといったリレーショナルデータベースが抱えるトランザクション処理能力のスケーラビリティに関する多くの問題が解決される。
しかし、NoSQLデータベースがこれらのデータベースのボトルネックに対する理想的な解決策ではないのには理由があります。
上記のすべての問題の解決策は、次のようなインメモリ分散キャッシュを使用することです。 NCache .NET Core アプリケーションのデプロイメントにおいて。 NCache は、.NETおよび.NET Core向けのオープンソースの分散キャッシュであり、非常に高速で線形にスケーラブルです。インメモリデータストアでありながら分散型でもあると考えてください。インメモリであるため非常に高速であり、分散型であるため線形にスケーラブルです。
NCache は、低コストのキャッシュ サーバー (Web アプリ サーバーと同じ構成だがメモリが多い) の TCP クラスターを構築し、これらすべてのサーバーのメモリと CPU リソースを XNUMX つの論理容量にプールするため、直線的にスケーラブルです。 NCache これにより、トランザクションの負荷が増大したときに、実行時にこのクラスターにキャッシュ サーバーを追加できるようになります。 それ以来 NCache すべてインメモリで処理されるため、非常に高速で、リレーショナルデータベースやNoSQLデータベースでは期待できないような、ミリ秒以下の応答時間を実現します。
線形スケーラビリティを提供することに加えて、次のような分散キャッシュ NCache データをインテリジェントにレプリケートするため、キャッシュ サーバーがダウンした場合でもデータの信頼性を確保しながら、パフォーマンスが損なわれることはありません。
NCache 以下の方法で.NET Coreアプリケーションを拡張できます。
.NET Core アプリケーションが直面する最も重要なボトルネックは「アプリケーション データベース」です。 NCache NoSQLデータベースとは異なり、 NCache 既存のリレーショナル データベースの使用を停止するように要求するものではありません。 SQL Server、Azure SQL Database、Oracle などをデータベースとして使用し続けながら、次を使用することで線形スケーラビリティを実現できます。 NCache リレーショナル データベース上にあります。 それの訳は NCache データベースとは異なり、リレーショナル データベースのスケーラビリティのボトルネックをすべて取り除きます。 NCache 実際には線形にスケーラブルです。
アプリケーション データ キャッシュを使用すると、データベースのボトルネックを解消できます。 NCache を使用すると、アプリケーション データをキャッシュし、高価なデータベースへのアクセスを削減できます。 データベース トラフィックの 80 ~ 90% が、 NCache。 これにより、データベースへの負荷が軽減され、データベースのパフォーマンスが向上し、速度を低下させることなく、より大きなトランザクション負荷を処理できるようになります。
アプリケーション データのキャッシュとは、リレーショナル データベースから取得したアプリケーション データをすべてキャッシュすることを意味します。 これは通常、ドメイン オブジェクト (エンティティとも呼ばれます) の形式です。 以下は、次のような分散キャッシュの使用方法の例です。 NCache アプリケーションデータキャッシング用。
Customer Load(string custId)
{
ICache cache = CacheManager.GetCache("myCache");
string key = "Customer:CustomerID:" + custId;
Customer cust = cache.Get<Customer>(key);
if (cust == null)
{
// Item not in cache so load from db
LoadCustomerFromDb(cust);
// Add item to cache for future reference
cache.Add(key, cust);
}
return cust;
}
図3:アプリのデータキャッシュにインメモリ分散キャッシュを使用する
もう一つのボトルネックになりうるのは、ASP.NET Core セッションを SQL Server またはスタンドアロンの MemoryCache に保存する場合です。どちらのオプションも、パフォーマンスとスケーラビリティに関して大きな制約があります。SQL Server ストレージは ASP.NET Core セッションには適しておらず、アプリケーション データと同様にすぐにボトルネックになります。
NCache は、他のストレージオプションよりもはるかに高速で拡張性が高いため、ASP.NET Core セッションを保存するのに最適な場所です。 NCache メモリ内処理であり、値が「オブジェクト」であるキーバリューインターフェースを提供するため、高速です。このオブジェクトはASP.NET Coreセッションに該当します。また、分散キャッシュであるため、スケーラブルです。
と、 NCache また、豊富なキャッシュトポロジーを通じてASP.NET Coreセッションをインテリジェントに複製するため、キャッシュサーバーがダウンしてもセッションデータが失われることはありません。この複製が必要な理由は、 NCache インメモリストアを提供し、メモリはストレージに違反しています。
NCache また、プロセス外に保存する前に必要な、ASP.NET Coreセッションのシリアル化も高速化します。 NCache .NETは、通常の.NETおよび.NET Coreのシリアル化よりも10倍高速な動的コンパクトシリアル化機能を使用することでこれを実現しています。この機能は、コードを変更することなく使用できます。
あなたが使用することができます NCache ASP.NET Core セッション ストアとして 2 つの方法で使用できます。
以下は、ASP.NET Core アプリケーションを構成する方法の例です。 NCache セッションプロバイダー:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Specify NCache as the session provider
services.AddNCacheSession(Configuration.GetSection("NCacheSettings"));
...
}
public void Configure(IApplicationBuilder app, ...)
{
// select NCache session provider for ASP.NET Core
app.UseNCacheSession();
...
}
}
図4:プラグイン NCache ASP.NET Core セッションとして
ASP.NET Coreアプリケーションは、本来であれば動的なコンテンツを持つものですが、一部のページでは、複数のリクエスト間でコンテンツやレスポンスが変化しないという状況に直面することがあります。しかし、これらのページはリクエストがあるたびに実行される必要があり、Webサーバーのリソースだけでなく、アプリケーションのすべての層に不要な負荷がかかります。結果として、パフォーマンスのボトルネックが発生し、アプリケーションのスケーラビリティが制限されます。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Turn on ASP.NET Core Response Cache with IDistributedCache
services.AddResponseCaching();
// Select NCache as IDistributedCache provider
services.AddNCacheDistributedCache(Configuration.GetSection("NCacheSettings"));
...
}
}
図5:プラグイン NCache ASP.NET Coreレスポンスキャッシュミドルウェアとして
ページ応答が変わらない繰り返しページ実行のオーバーヘッドに対処するため、ASP.NET Core は ASP.NET Response Cache Middleware と呼ばれるページ応答キャッシュメカニズムを提供しています。 NCache ASP.NET Core では IDistributedCache インターフェイスが実装されているため、シームレスにプラグインできます。 NCache ASP.NET Core レスポンスキャッシュミドルウェアとして使用できます。
だから、使用することができます NCache ASP.NET Coreページのレスポンスを一定期間キャッシュすることで、次回同じページが同じパラメータで呼び出されたときに、ページ全体を再度実行する代わりにキャッシュされたレスポンスを再取得できます。以下に、設定方法のコード例を示します。 NCache ASP.NET Core レスポンスキャッシュミドルウェアとして使用できます。
ASP.NET Core アプリケーションがリアルタイム Web アプリケーションである場合、リアルタイム動作を実現するために ASP.NET Core SignalR を使用している可能性が高いです。リアルタイム Web アプリケーションは、サーバーからクライアントへ高頻度で更新情報を提供します。このようなアプリケーションの例としては、ゲーム、オークション、投票、ソーシャル ネットワークなどが挙げられます。
ASP.NET Core アプリケーションが負荷分散されたマルチサーバー環境で実行されている場合、複数の Web サーバー間でイベントを共有するために、ASP.NET Core SignalR バックプレーン プロバイダーを使用する必要があります。また、このバックプレーンはスケーラブルでなければなりません。そうでない場合、ASP.NET Core SignalR アプリケーションはパフォーマンスのボトルネックに直面し始めます。
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// Specify NCache as the ASP.NET Core SignalR Backplane
services.AddSignalR().AddNCache(ncacheOptions =>
{ ncacheOptions.CacheName = "myPartitionedCache"; });
...
}
public void Configure(IApplicationBuilder app, ...)
{
// Use SignalR in ASP.NET Core
app.UseSignalR(config => { config.MapHub<MessageHub>("/messages"); });
...
}
}
図6:プラグイン NCache ASP.NET Core SignalR バックプレーンプロバイダーとして
NCache ASP.NET Core SignalRバックプレーンプロバイダを実装しました。 NCacheの ASP.NET Core SignalR バックプレーン プロバイダーは、Pub/Sub メッセージング機能を使用します。 NCache 完全にメモリ上で動作するため、非常に高速です。これにより、ASP.NET Core SignalR アプリケーションは、すべての Web サーバー間、ひいてはクライアントへの SignalR イベントの伝播を高速化できます。
また、これにより、リアルタイム Web アプリケーションの応答性が向上し、頻繁な更新をクライアントに配信できるようになります。 また、パフォーマンスのボトルネックを恐れることなく、クライアントの数を増やし続けたり、Web サーバーを追加したりすることもできます。
.NET CoreアプリケーションでPub/Subメッセージングまたはイベントを使用する必要がある場合、おそらく完全なインメモリではなく、すべてのメッセージをディスクに保存するPub/Subメッセージングプラットフォームを使用しているでしょう。そのため、アプリケーションのトランザクション数が非常に多い場合、パフォーマンスのボトルネックになりやすくなります。
NCache また、完全にインメモリであるため、超高速な Pub/Sub メッセージングも提供します。 そして、すべてのメッセージを別のメッセージに複製します。 NCache いずれかのサーバーがダウンした場合でもデータが失われないようにするためのサーバーです。
したがって、.NET Core アプリケーションが NCache Pub/Sub メッセージング プラットフォームとして、超高速のパフォーマンスと直線的なスケーラビリティを実現します。 NCache それ自体は線形にスケーラブルです。
以下は、によって提供される Pub/Sub メッセージングの使用方法の例です。 NCache .NET Core アプリケーションにおいて。
private void PublishMessage (string topicName)
{
ITopic topic = _cache.MessagingService.GetTopic(topicName);
Order order = Order.GenerateOrder<Order>();
// Publish message containing "order" with expiry
Message message = new Message(order, new TimeSpan(0, 0, 15));
topic.Publish(message, DeliveryOption.All, true);
}
private ITopicSubscription SubscribeMessage (string topicName)
{
ITopic topic = _cache.MessagingService.GetTopic(topicName);
// Subscribes to the topic. Message delivered to MessageReceivedCallback
return topic.CreateSubscription(MessageReceivedCallback);
}
static void MessageReceivedCallback(object sender, MessageEventArgs args) { ... }
図7:.NET CoreアプリでのPub/Subメッセージングの使用
.NET Core アプリケーションが解消すべき最大の拡張性ボトルネックは、アプリケーション データベースにあります。この領域では、アプリケーション データ キャッシュによって、アプリケーションは高いパフォーマンスと線形的な拡張性を実現できます。その理由は単純です。ほとんどの .NET Core アプリケーションは、データベースとの間で大量のデータをやり取りするからです。
アプリケーション データのキャッシュに関して人々が抱く最大の懸念は、キャッシュが古くなることです。つまり、別のユーザーまたは別のアプリケーションによってデータベース内ですでに変更されている古いバージョンのデータがキャッシュに含まれているということです。
キャッシュが古くなってしまうことへの懸念が非常に強いため、大多数の人は読み取り専用データまたは静的データ (参照データ) のみをキャッシュします。 ただし、この読み取り専用データは、ルックアップ テーブルやその他の参照データの形式のデータ全体の 20% にすぎません。 データベース内のデータの大部分は、顧客、アカウント、アクティビティなどを含むトランザクションデータです。そして、このトランザクションデータをキャッシュしないと、キャッシュのメリットを十分に得ることができません。
したがって、キャッシュが古くなることを心配せずに、あらゆる種類のデータをキャッシュできる場合に、キャッシュの本当のメリットが得られます。 NCache は、この問題に対処するための多くの機能を提供します。
キャッシュを最新の状態に保つ最も効果的な方法は、キャッシュを常にデータベースと同期させておくことです。 NCache 次のように、さまざまなデータベースに対してこれを行うことができます。
キャッシュを SQL Server と同期するときは、次のことを尋ねます。 NCache 自分自身を SQL Server のクライアントとして登録し、SQL クエリベースのデータセットとともに SqlDependency 呼び出しを発行します。 その後、SQL Server がこのデータセットに変更を検出すると、 NCache それについて
private static void CreateSqlDependency (Product product)
{
string connectionString = "Data Source=localhost;Database=northwind;...";
// SQL stmt on which the SQL Dependency is created in SQL Server
string sqlStmt = "SELECT ProductID, ProductName, QuantityPerUnit, UnitPrice " +
"FROM dbo.PRODUCTS WHERE ProductID = " + product.Id;
CacheDependency sqlDependency = new SqlCacheDependency(connectionString, sqlStmt);
CacheItem cacheItem = new CacheItem(product) { Dependency = sqlDependency };
string key = "Product:ProductId:" + product.Id; ;
cache.Add(key, cacheItem);
}
図 8: SqlDependency を使用してキャッシュを SQL Server と同期する
その後、 NCache この項目はキャッシュから削除されるため、アプリケーションが次回この項目を必要とするときに、データベースから最新のコピーをフェッチする必要があります。 リードスルー ハンドラー (以下を参照) を使用している場合は、 NCache データベースから最新のコピーを自動的に再ロードすることもできます。 以下は、SqlDependency を使用してキャッシュを SQL Server と同期する方法の例です。
リードスルー キャッシュは、開発してキャッシュに提供したリードスルー ハンドラーを呼び出すことによって、データベースからデータを読み取ることができるキャッシュです。 同様に、ライトスルー キャッシュは、開発してキャッシュに提供したライトスルー ハンドラーを呼び出すことによって、データの変更をデータベースに書き込むことができます。 ライトビハインド キャッシュは、データベースの更新が非同期で行われる点を除いてライトスルーと同じです。
リードスルー、ライトスルー、ライトビハインドは、.NET Core アプリケーションに以下のような多くのメリットをもたらします。
以下は、Read-through を使用する方法の例です。 NCache.
// Read through handler for SQL Server
public class SqlReadThruProvider : Runtime.DatasourceProviders.IReadThruProvider
{
public void Init(IDictionary parameters, string cacheId) {}
public void Dispose() {}
// Get object from the database/data-source based on the key
public ProviderCacheItem LoadFromSource(string key) {}
// Bulk-Get objects from the database/data-source based on the keys
public IDictionary<string, ProviderCacheItem> LoadFromSource(ICollection<string> keys)
{}
}
図 9: リードスルー ハンドラーの使用 NCache
すべてのデータをキャッシュすることに慣れたら、大量のデータを分散キャッシュに置き始めることができます。 ここで、データを迅速かつ簡単に見つける方法という別の独特な問題に直面することになります。 ほとんどの分散キャッシュはキーと値のストアであるため、キーだけですべてのデータを追跡することは非常に困難になります。
これはどこですか? NCache では、キャッシュからデータをすばやく検索するためのさまざまな方法が提供されます。 例としては次のものが挙げられます。
以下は、LINQ ベースのクエリを使用する方法の例です。 NCache.
// Search the cache based on object attributes by using LINQ
IQueryable>Product< products = new NCacheQuery<Product>(_cache);
var result = from product in products
where product.Id > 10
select product;
if (result != null)
{
foreach (Product p in result1)
{
// Process each “product” fetched from the database
Console.WriteLine("ProductID : " + p.Id);
}
}
図 10: LINQ クエリの使用 NCache
高トラフィックの.NET Coreアプリケーションは、特にピーク時にはダウンすることが許されません。このようなタイプのアプリケーションには、優れたインメモリ分散キャッシュのような、3つの非常に重要なアーキテクチャ目標があります。 NCache 満たします。
以下でそれぞれについて説明していきます。
NCache は、アプリケーションに非常に近いローカル キャッシュであるクライアント キャッシュを提供します。 InProc (アプリケーション プロセス内に存在することを意味します) またはローカル OutProc のいずれかになります。 いずれの場合でも、このアプリ サーバー上のアプリケーションが現時点で必要とするキャッシュ データのサブセットへの非常に高速なアクセスが可能になります。 同時にクライアント キャッシュはキャッシュ層との同期を維持するため、キャッシュ層内の他のユーザーまたはアプリケーションによって変更されたデータはすぐにクライアント キャッシュに伝播されます。 クライアントを使用すると、非常にスケーラブルなキャッシュ層の一部でありながら、InProc 速度を実現できます。
の最も重要なアーキテクチャの目標のXNUMXつ NCache キャッシング トポロジを通じてデータの信頼性を備えた線形スケーラビリティを実現することです。 ここにあるいくつかの NCache キャッシングトポロジ これらの両方の目標を達成するのに役立ちます。
の最も重要なアーキテクチャの目標のXNUMXつ NCache 高可用性とキャッシュの弾力性を実現することです。 これは、次のアーキテクチャ機能を通じて行われます。
©著作権 Alachisoft 2002 - . All rights reserved. NCache はダイヤテック株式会社の登録商標です。