オブジェクトへのアクセスと操作の容易さを提供することについて話すときはいつでも、 オブジェクトリレーショナルマッパー (ORM)は必ず登場します。 Entity Framework CoreやNHibernateなどのORMは、 プレーンオールドCLRオブジェクト(POCO) データベース情報へのインスタンス、関連付け、制約などの管理。
ただし、コードからSQLへの機能を使用すると、パフォーマンスの遅延やパフォーマンスの低下につながる可能性があり、最も一般的な原因はN+1の問題です。 StackExchangeにいる人々は、インフラストラクチャのニーズに対するORMのパフォーマンスに満足せず、思いついた。 ダッパー、ADO.NETのマイクロORM軽量ラッパーであり、非常に高速で、データベースモデルへのオブジェクトマッピングを非常に簡単かつ直感的にします。
NCache 詳細 オブジェクトリレーショナルマッピング ダッパー
Dapperとの統合 NCache
Dapperは、主に IDb接続 クラスを作成し、複雑になることが多いADO.NET操作のファサードを提供します。 それが軽量性と高速性の大きな理由です。 ただし、データベースへのラウンドトリップを回避するためにデータがメモリ内にとどまるようにする場合は、次を使用します。 NCache。 のような分散キャッシュを使用 NCache、次の図に示すように、データソースプロバイダーを使用してパフォーマンスをさらに調整できます。
NCache 詳細 データソースプロバイダー Dapperを使用したデータソース
データソースプロバイダーとのサードパーティのDapper
データソースプロバイダーは、読み取りと書き込みの目的でバックエンドマスターデータソースにアクセスする必要がある場合に最適なソリューションです。 これらのプロバイダーは、Dapper操作をサーバー側にオフロードします。
私のアプリケーションがデータソースプロバイダーを備えたDapperライブラリにどのように対応しているかを見てみましょう。
この単純な実装 リードスルー を使用してデータソースから直接データを読み取るためのDapperライブラリを備えたプロバイダー NCache 結果をキャッシュすると、アプリケーションのパフォーマンスが向上します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public ProviderCacheItem LoadFromSource(string key) { var customerId = key.Replace("Customer:CustomerID:", "").Trim(); var commandDefinition = new CommandDefinition($@" SELECT * FROM dbo.Customers WHERE CustomerID = @cId", new { cid = customerId }, flags: CommandFlags.NoCache); var customer = Connection.Query<Customer>(commandDefinition).FirstOrDefault(); var providerCacheItem = new ProviderCacheItem(customer) { Dependency = GetCustomerSqlDependency(customerId), ResyncOptions = new ResyncOptions(true) }; return providerCacheItem; } |
NCache 詳細 データソースプロバイダー Dapperを使用したデータソース
同様に、データをデータストアに直接書き込むには、 NCache 提供 ライトスルー キャッシュされたコピーを保持しながら、データを取得してデータストアに書き込むプロバイダー。
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 |
public OperationResult WriteToDataSource(WriteOperation operation) { Customer customer = null; if (operation.OperationType == WriteOperationType.Add || operation.OperationType == WriteOperationType.Update) { customer = operation.ProviderItem.GetValue<Customer>(); } if (operation.OperationType == WriteOperationType.Add) { var commandDefinition = new CommandDefinition(// INSERT sql command for customer data with customer id , customer, flags: CommandFlags.NoCache); Connection.Execute(commandDefinition); } else if (operation.OperationType == WriteOperationType.Update) { var commandDefinition = new CommandDefinition(// UPDATE sql command for customer data with customer id, customer, flags: CommandFlags.NoCache); Connection.Execute(commandDefinition); } else if (operation.OperationType == WriteOperationType.Delete) { var customerId = operation.Key.Replace("Customer:CustomerID:", "").Trim(); var commandDefinition = new CommandDefinition(// delete sql script for given customer id , new { cId = customerId }, flags: CommandFlags.NoCache); Connection.Execute(commandDefinition); } } |
NCache 詳細 データソースプロバイダー Dapperを使用したデータソース
この詳細な解決策はどこにありますか NCache Dapperライブラリを使用して、データストアにデータを入力して読み取ります GitHubの.
私が気づいた利点をリストアップします NCache-Dapperコラボレーション。
メリット#1:同期用のデータソースプロバイダー
古いデータをキャッシュに保持しないようにするために、データソースプロバイダーは データベース依存機能 キャッシュされたデータとデータベース内のデータの同期を確認します。 キャッシュを再同期するためのすべての操作は、クライアントの関与なしにサーバー側で実行されます。
メリット#2:クライアントアプリケーションをスペアするデータソースプロバイダー
データストアに変更を加えたいとしましょう。データストア全体を完全に変更した場合でも、スキーマの更新、テーブルのバリエーションは次のようになります。 NCache プロセスを簡素化します。 と NCache クライアントアプリケーションを変更する必要のないデータソースプロバイダー。データソースの実装を更新するだけで十分です。
メリット#3:スケーラブル NCache クエリ結果を保存する
アプリケーションの複数のインスタンスが、キャッシュを共有するロードバランサー(サーバーファーム、Kubernetesクラスターなど)の背後で実行されている環境でアプリケーションが実行されている場合、これが NCache インスタンスのXNUMXつがデータソースにクエリを実行すると、結果は分散キャッシュに保存されるため、他のインスタンスが同じ結果をクエリすると、データソースへのラウンドトリップを行わなくてもキャッシュから直接取得されます。
これにより、データベースへのヒットが減り、スケーラブルになります。 NCache クラスターをダウンさせることなく、クラスターをリアルタイムでスケールアウトするだけで、要求の負荷の増加に対応できます。
NCache 詳細 データソースプロバイダー Dapperを使用したデータソース
それを一掃する
ORMが使いやすさを提供する場合、ORMはアプリケーションに負担をかけ、予期しないパフォーマンスの低下を引き起こす可能性もあります。 ただし、Dapperは非常に軽量であり、効率的なクエリとコマンドを設計するときにこの知識を念頭に置く必要がある開発者により多くの制御を提供します。
これで、熟練したものができたので、次のような分散キャッシュを使用してみませんか。 NCache それと? NCacheは、メモリ内にあり、拡張が容易な機能を備えており、Dapperライブラリを非常に正確に補完するため、驚くべき結果が得られます。 だから、取得に行きます NCache 今!