118

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

序文:

私は最近EntityFrameworkについて多くの調査を行っていますが、クエリがウォームアップされていないときのパフォーマンス、いわゆるコールドクエリが気になります。

EntityFramework5.0のパフォーマンスに関する考慮事項の記事を読みました。著者は、ウォームクエリとコールドクエリの概念とそれらの違いを紹介しました。私もそれらの存在を知らずに気づきました。ここで言及する価値があると思いますが、私は6か月しか経験がありません。

これで、パフォーマンスの観点からフレームワークをよりよく理解したい場合に、さらに調査できるトピックがわかりました。残念ながら、インターネット上のほとんどの情報は古くなっているか、主観的に肥大化しているため、ウォームクエリとコールドクエリのトピックに関する追加情報を見つけることができません。

基本的に、これまでに気付いたのは、再コンパイルする必要があるとき、またはヒットをリサイクルするときはいつでも、最初のクエリが非常に遅くなっていることです。予想どおり、後続のデータ読み取りは高速(主観的)です。

Windows Server 2012、IIS8、およびSQL Server 2012に移行します。ジュニアとして、私は実際に、残りの前にそれらをテストする機会を獲得しました。彼らがウォーミングアップモジュールを導入してくれて、私のアプリケーションがその最初のリクエストに対応できるようになることをとてもうれしく思います。ただし、EntityFrameworkのウォーミングアップを続行する方法がわかりません。

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

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

私が考えていることは、常識に従って、おそらく間違ったアプローチです:

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

質問:

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

5 に答える 5

54
  • Entity Frameworkでいつでも高可用性を実現するための最良のアプローチは何でしょうか?

事前に生成されたビューと静的にコンパイルされたクエリを組み合わせて使用​​できます。

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

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

多くのTPT継承を使用しないでください(これはEFの一般的なパフォーマンスの問題です)。継承階層を構築しすぎたり、広すぎたりしないでください。一部のクラスに固有の2〜3個のプロパティだけでは、独自の型を必要としない場合がありますが、既存の型のオプションの(null許容)プロパティとして処理できます。

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

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

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

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

また、構成ファイルを変更したり、アセンブリを変更したりすると、再起動することになると思います。

于 2012-11-28T12:58:41.060 に答える
8

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

一般に、ローカルにキャッシュされた情報が古くなった場合、またはトランザクションである必要がある場合にのみIOベースのデータ要求を要求するように分散アーキテクチャを設計するように努める必要があります。「ネットワーク経由」のデータ要求は、通常、ローカルのメモリキャッシュ取得よりも取得に10〜1000倍長くかかります。この1つの事実だけでも、「ローカルvs.リモート」データの問題と比較して、「コールドvs.ウォームデータ」についての議論は重要ではないことがよくあります。

于 2012-11-27T14:13:09.000 に答える
7

一般的なヒント。

  • アクセスされるもの要求時間など、厳密なログ記録を実行します。
  • アプリケーションを初期化するときにダミーリクエストを実行して、前の手順で取得した非常に遅いリクエストをウォームブートします。
  • それが本当の問題でない限り、最適化を気にしないでください。アプリケーションの利用者と連絡を取り、尋ねてください。最適化が必要なものを理解するためだけに、継続的なフィードバックループを快適に利用できます。

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

  • 複雑さの軽減-フレームワークの変更に関係なく機能する方法でアプリケーションをウォーミングアップしており、正しい方法で実行するために、ファンキーなAPI/フレームワークの内部を把握する必要はありません。
  • より広いカバレッジ-遅いリクエストに関連して、キャッシュのすべてのレイヤーを一度にウォームアップしています。

キャッシュがいつ「コールド」になるかを説明します。

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

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

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

于 2012-11-29T05:43:26.110 に答える
4

あなたが述べたように、あなたがする必要があるのは本当にすべてである「事前に生成されたビュー」を使用してください。

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

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

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

ショートカット...

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

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

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

于 2012-11-23T15:13:14.850 に答える