web-dev-qa-db-ja.com

Entity Frameworkを「ウォームアップ」する方法は?いつ「風邪」になりますか?

いいえ、2番目の質問に対する答えは冬ではありません。

序文:

私は最近Entity Frameworkについて多くの研究を行ってきましたが、気になり続けるのは、クエリがウォームアップされていないときのパフォーマンス、いわゆるコールドクエリです。

Entity Framework 5.0の パフォーマンスに関する考慮事項 の記事を読みました。著者は、WarmおよびColdクエリの概念とそれらの違いを紹介しました、それらの存在を知らずに自分自身にも気づきました。ここでは、たった6か月の経験しかありません。

これで、パフォーマンスの観点からフレームワークをよりよく理解したい場合に、さらに研究できるトピックがわかりました。残念ながら、インターネット上の情報のほとんどは時代遅れであるか、主観で肥大化しているため、WarmvsColdトピックを照会します。

基本的に私がこれまで気づいたのは、再コンパイルする必要があるときやリサイクルのヒット時に、最初のクエリが非常に遅くなるということです。その後のデータ読み取りは、予想どおり高速です(subjective)。

Windows Server 2012、IIS8、およびSQL Server 2012に移行する予定です。ジュニアとして、実際にテストを行う機会を獲得しました。私のアプリケーションがその最初のリクエストに対応できるようにするウォームアップモジュールを導入してくれてとてもうれしいです。ただし、Entity Frameworkのウォームアップを進める方法がわかりません。

私がすでに知っていることはやる価値がある:

  • 提案に従って、事前にビューを生成します。
  • 最終的にモデルを別のアセンブリに移動します。

私が常識的に行って考えること、おそらく間違ったアプローチ

  • モデルをウォームアップ、生成、検証するために、アプリケーションの開始時にダミーデータの読み取りを行います。

質問:

  • いつでもEntity Frameworkで高可用性を実現するための最良のアプローチは何でしょうか?
  • どのような場合に、Entity Frameworkは再び「コールド」になりますか? (再コンパイル、リサイクル、IIS再起動など)
118
Peter
  • いつでもEntity Frameworkで高可用性を実現するための最良のアプローチは何でしょうか?

事前に生成されたビューと静的にコンパイルされたクエリを混在させることができます。

Static CompiledQuerys は、記述が迅速かつ簡単であり、パフォーマンスの向上に役立つため、優れています。ただし、EF5では、EFはクエリ自体を自動コンパイルするため、すべてのクエリをコンパイルする必要はありません。唯一の問題は、キャッシュがスイープされると、これらのクエリが失われる可能性があることです。そのため、非常にまれにしか発生しないが高価なクエリについては、独自のコンパイル済みクエリへの参照を保持したいのです。これらのクエリを静的クラスに入れると、最初に必要になったときにコンパイルされます。これは一部のクエリでは遅すぎる可能性があるため、アプリケーションの起動中にこれらのクエリのコンパイルを強制することができます。

あなたが言及しているように、ビューを事前生成することも可能です。特に、コンパイルに非常に時間がかかり、変更されないクエリの場合。これにより、パフォーマンスのオーバーヘッドをランタイムからコンパイル時間に移動できます。また、これにより遅延が発生することはありません。しかし、もちろんこの変更はデータベースにも適用されるため、対処するのはそれほど簡単ではありません。コードはより柔軟です。

多くのTPT継承を使用しないでください(EFの一般的なパフォーマンスの問題です)。継承階層を深すぎたり広すぎたりしないでください。一部のクラスに固有の2〜3個のプロパティだけでは、独自の型を必要とするのに十分ではないかもしれませんが、既存の型に対するオプションの(nullable)プロパティとして処理できます。

単一のコンテキストを長時間保持しないでください。各コンテキストインスタンスには独自の1次キャッシュがあり、大きくなるとパフォーマンスが低下します。コンテキストの作成は安価ですが、キャッシュされたコンテキストのエンティティ内の状態管理は高価になる可能性があります。他のキャッシュ(クエリプランとメタデータ)はコンテキスト間で共有され、AppDomainと共に消滅します。

全体として、コンテキストを頻繁に割り当てて、短時間だけ使用すること、アプリケーションをすばやく起動できること、ほとんど使用されないクエリをコンパイルし、パフォーマンスが重要で頻繁に使用されるクエリに対して事前生成されたビューを提供することを確認する必要があります。

  • どのような場合に、Entity Frameworkは再び「コールド」になりますか? (再コンパイル、リサイクル、IIS再起動など)

基本的に、AppDomainを失うたびに。 IISは再起動を 29時間 ごとに実行するため、インスタンスが存在することを保証することはできません。また、アクティビティがない一定時間後にAppDomainもシャットダウンされます。いくつかの初期化を非同期的に行うことができます(ただし、マルチスレッドの問題に注意してください)。アプリケーションのダミーページを呼び出すスケジュールされたタスクを使用して、 AppDomainは死にかけていますが、最終的にはそうなります。

また、構成ファイルを変更したり、アセンブリを変更したりすると、再起動が行われると想定しています。

55
Andreas

すべての呼び出しで最大のパフォーマンスを求めている場合は、アーキテクチャを慎重に検討する必要があります。たとえば、サーバーで頻繁に使用されるルックアップを事前キャッシュすることは理にかなっているかもしれませんRAMすべてのリクエストでデータベース呼び出しを使用する代わりに、アプリケーションがロードされるとき。ただし、同時実行の問題を回避するために、キャッシュされたデータに影響する変更が行われるたびに、適切に動作する有効期限ポリシーを設定するか、常にキャッシュをクリアする必要があります。

一般に、ローカルにキャッシュされた情報が古くなったり、トランザクションが必要になったときにIOベースのデータ要求のみを必要とする分散アーキテクチャを設計するよう努力する必要があります。この1つの事実だけで、「ローカルとリモート」のデータの問題と比較して、「コールドとウォームのデータ」に関する議論は重要ではありません。

9
mcstar

一般的なヒント。

  • アクセスされるものおよび要求時間を含む厳密なロギングを実行します。
  • アプリケーションをウォームブートするために初期化するときにダミーのリクエストを実行します非常に遅い前のステップで取得したリクエスト。
  • それが本当の問題でない限り、最適化を気にせず、アプリケーションの消費者と通信して尋ねてください。 最適化が必要なものを把握するためだけに、連続的なフィードバックループを快適に使用できます。

次に、ダミーリクエストが間違ったアプローチではない理由を説明します。

  • それほど複雑ではない-フレームワークの変更に関係なく機能する方法でアプリケーションをウォームアップしているため、ファンキーなAPI /フレームワーク内部を理解する必要はありません正しい方法
  • より大きいカバレッジ-低速なリクエストに関連するキャッシュのすべてのレイヤーを一度にウォームアップしています。

キャッシュが「コールド」になるタイミングを説明します。

これは、キャッシュを適用するフレームワーク内の任意のレイヤーで発生します。 パフォーマンスページの上部 に説明があります。

  • キャッシュを失効させる可能性のある変更の後にキャッシュを検証する必要がある場合、これはタイムアウトまたはよりインテリジェントになる可能性があります(つまり、キャッシュされたアイテムの変更)。
  • キャッシュアイテムが削除されると、これを行うためのアルゴリズムは リンクしたパフォーマンス記事 の「キャッシュ削除アルゴリズム」セクションで説明されますが、簡単に説明します。
    • LFRU(最低頻度-最近使用された)ヒットカウントおよび経過時間のキャッシュ。800アイテムの制限。

あなたが言及した他のこと、特にIISの再コンパイルと再起動は、メモリキャッシュの一部またはすべてをクリアします。

8
udoprog

すでに述べたように、実際に必要なのは「生成済みのビュー」だけです。

link :「ビューが生成されると、それらも検証されます。パフォーマンスの観点から見ると、ビュー生成のコストの大部分は実際にはビューの検証です」

これは、モデルアセンブリをビルドするときにパフォーマンスノックが発生することを意味します。コンテキストオブジェクトは、「コールドクエリ」をスキップし、コンテキストオブジェクトのライフサイクルの期間および後続の新しいオブジェクトコンテキストの応答性を維持します。

無関係なクエリを実行しても、システムリソースを消費する以外の目的はありません。

ショートカット...

  1. 事前生成されたビューの余分な作業をすべてスキップします
  2. オブジェクトコンテキストを作成する
  3. その甘い無関係なクエリを起動します
  4. 次に、プロセスの間オブジェクトコンテキストへの参照を保持します(推奨されません)。
3
hotpie

このフレームワークの経験はありません。しかし、他のコンテキストでは、例えばSolr、完全にダミーの読み取りは、DB(またはインデックス)全体をキャッシュできない限り、あまり役に立ちません。

より良い方法は、クエリをログに記録し、ログから最も一般的なクエリを抽出し、それらを使用してウォームアップすることです。続行する前に、ウォームアップクエリをログに記録しないか、ログから削除しないでください。

2
estani