エンティティフレームワークを「ウォームアップ」する方法 いつ「冷たく」なりますか?


118

いいえ、2つ目の質問の答えは冬ではありません。

序文:

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

私が通過したパフォーマンスに関する考慮事項の Entity Frameworkの5.0についての記事。著者は、ウォームクエリとコールドクエリの概念とそれらの違いを紹介しました。これらも、その存在を知らずに気づきました。ここで、私がたった6か月しか経験していないことに言及する価値があるでしょう。

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

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

私たちは、Windows Server 2012、IIS8、SQL Server 2012に移行する予定です。私はジュニアとして、実際にそれらをテストする機会を得ました。彼らが私の最初のリクエストのために私のアプリケーションを準備するウォーミングアップモジュールを導入してとても嬉しいです。ただし、Entity Frameworkのウォームアップの進め方がわかりません。

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

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

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

  • 物事をウォームアップし、モデルを生成して検証するために、Application Startでダミーデータを読み取ります。

質問:

  • Entity Frameworkでいつでも高可用性を実現するには、どのような方法が最適ですか?
  • Entity Frameworkはどのような場合に「コールド」になりますか?(再コンパイル、リサイクル、IIS再起動など)

これがビューの生成なのか、クエリのコンパイルなのかがわかります。これがビューの生成である場合、プリコンパイルされたビューを使用します。これがクエリの場合-大きく複雑な階層がありますか?高価なものは通常、アプリドメインごとに1回発生してキャッシュされるため、アプリドメインがアンロードされて新しいドメインが作成されると、この種の問題が発生します。
Pawel

ビュー生成については既に@Pawelで説明しましたが、階層は複雑ではなく、少しでもありません。しかし、問題も主要です。あなたが言ったことに続いて、アプリドメインがいつアンロードされるかを調査します。ただし、それでも、あなたが言ったように、アプリドメインがアンロードされた場合に備えてEntity Frameworkを暖める他の問題は解決しません。この時点で、アプリケーションドメインは、それが必要以上にアンロードされているようだと、リサイクルは夜だけで、アイドリングが0に設定されている理由私はわからない
ピーター

4
なぜダミーデータの読み取りを行うのが間違ったアプローチだと思いますか?
Josh Heitzman、2012年

5
気分が悪いだけで、気づかないほどエレガントなものがあるのではないかと思いました。しかし、それが唯一の解決策であり、知識の豊富な人が他に方法がないことを確認できる場合は、私はそれを採用します。
Peter

1
(トラフィックが少ないために)非アクティブな状態が一定期間続いた後にアプリケーションプールがシャットダウンするときに発生した問題の1つは、ページの1つに設定された時間間隔でリクエストを送信するサービスを作成することです。これにより、最初のリクエストでアプリプールが再起動されるまでの長い遅延が回避されます。または、www.pingalive.comなどの無料サービスを使用して、ドメイン/ IPにpingすることもできます。これは、キャッシュされたオブジェクトが期限切れになる前に消去されないようにするのにも役立ちます。
hatsrumandcode 2013

回答:


55
  • Entity Frameworkでいつでも高可用性を実現するには、どのような方法が最適ですか?

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

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

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

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

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

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

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

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

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


アンドレ、ありがとう、それが私が必要としていたことでした。
ピーター

@Andreas実際に静的にコンパイルされたクエリを使用しても、最初の実行が長すぎます。それ以外の方法でウォームアップする方法はありますか:ウォームアップ、モデルの生成、検証を行うために、Application Startでダミーデータの読み取りを行います。
manishKungwani 2013

@Andreasそれで、Entity framework5はそれを必要とするかどうか?ef5で使用する場合、何が違うのですか(まだ遅いか、少し打者か、違いがないということですか?)
qakmak 14年

「静的なCompiledQueryは、すばやく簡単に記述でき、パフォーマンスの低下に役立つため、優れています。」パフォーマンスの低下?
Mathemats

9

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

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


これは、エンティティフレームワークの生のパフォーマンスに夢中になる一方で、私がよく無視している良い点です。私はこれをさらに調査し、キャッシングの原則についてさらに研究します。しかし、EFの観点から見た「コールドvsウォーム」は、まだ理解したいものです。
Peter

2
「この1つの事実だけでも、「ローカルデータとリモートデータ」の問題と比較して、「コールドデータとウォームデータ」についての議論は重要ではありません。」あんまり。ローカルにキャッシュされていない場合(最初はキャッシュされません)、キャッシュを準備するために、EFをヒットし、初期化の痛みを経験する必要があります。キャッシュが初期化されていないのと同じ場所で、EFは初期化されません。したがって、EFの初期化時間が唯一の問題である場合は、キャッシュの層を追加しても役に立たない可能性がありますが、さらに複雑な層が追加されます...
MikeJansen

8

一般的なヒント。

  • アクセス内容リクエスト時間など厳密なロギングを実行します
  • アプリケーションを初期化するときにダミーの要求を実行して、前のステップで取得した非常に遅い要求をウォームブートします。
  • 実際の問題でない限り、わざわざ最適化を行わないでください。アプリケーションのコンシューマとコミュニケーションを取り、質問してください。最適化が必要なものを見つけるだけの場合は、継続的なフィードバックループを快適に利用できます

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

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

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

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

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

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


これは、もう1つの役立つ回答です。
ピーター

3

あなたが述べたように、実際にあなたがする必要があるのは「事前に生成されたビュー」を使用することです。

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

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

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

ショートカット...

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


2

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.