Wie kann man das Entity Framework „aufwärmen“? Wann wird es „kalt“?

118

Nein, die Antwort auf meine zweite Frage ist nicht der Winter.

Vorwort:

Ich habe in letzter Zeit viel über Entity Framework recherchiert und etwas, das mich immer wieder stört, ist die Leistung, wenn die Abfragen nicht aufgewärmt sind, sogenannte Cold-Abfragen.

Ich habe den Artikel zu Leistungsüberlegungen für Entity Framework 5.0 durchgearbeitet. Die Autoren stellten das Konzept der warmen und kalten Abfragen vor und wie sie sich unterscheiden, was ich auch selbst bemerkte, ohne von ihrer Existenz zu wissen. Hier ist es wahrscheinlich erwähnenswert, dass ich nur sechs Monate Erfahrung hinter meinem Rücken habe.

Jetzt weiß ich, zu welchen Themen ich zusätzlich recherchieren kann, wenn ich das Framework in Bezug auf die Leistung besser verstehen möchte. Leider sind die meisten Informationen im Internet veraltet oder voller Subjektivität, daher kann ich keine zusätzlichen Informationen zum Thema Warm vs Cold- Abfragen finden.

Grundsätzlich ist mir bisher aufgefallen, dass meine anfänglichen Anfragen sehr langsam werden, wenn ich neu kompilieren muss oder die Recycling-Treffer. Alle nachfolgenden gelesenen Daten sind erwartungsgemäß schnell ( subjektiv ).

Wir werden auf Windows Server 2012, IIS8 und SQL Server 2012 migrieren und als Junior habe ich mir tatsächlich die Gelegenheit erarbeitet, sie vor dem Rest zu testen. Ich bin sehr froh, dass sie ein Aufwärmmodul eingeführt haben, das meine Bewerbung für diese erste Anfrage vorbereitet. Ich bin mir jedoch nicht sicher, wie ich mein Entity Framework aufwärmen soll.

Was ich bereits weiß, lohnt sich:

  • Generieren Sie meine Ansichten im Voraus wie vorgeschlagen.
  • Verschieben Sie meine Modelle schließlich in eine separate Baugruppe.

Was ich mit gesundem Menschenverstand für wahrscheinlich falsch halte :

  • Beim Anwendungsstart werden Dummy-Daten gelesen, um die Modelle aufzuwärmen, zu generieren und zu validieren.

Fragen:

  • Was wäre der beste Ansatz, um jederzeit eine hohe Verfügbarkeit in meinem Entity Framework zu haben?
  • In welchen Fällen wird das Entity Framework wieder "kalt"? (Neukompilierung, Recycling, IIS-Neustart usw.)
Peter
quelle
Finden Sie heraus, ob dies die Ansichtsgenerierung oder die Abfragekompilierung ist, die Sie am meisten trifft. Wenn dies view gen ist, verwenden Sie vorkompilierte Ansichten. Wenn dies die Abfragen sind - haben Sie eine große komplizierte Hierarchie? Beachten Sie, dass teure Dinge normalerweise einmal pro App-Domain passieren und zwischengespeichert werden. Daher treten diese Probleme auf, wenn die App-Domain entladen und eine neue erstellt wird.
Pawel
Ich habe bereits die Ansichtsgenerierung @Pawel erwähnt, die Hierarchie ist nicht kompliziert, nicht einmal ein bisschen. Das Problem ist aber auch das Hauptproblem. Nach Ihren Aussagen werde ich untersuchen, wann die App-Domain entladen wird. Dies hilft jedoch immer noch nicht bei dem anderen Problem, das das Entity Framework erwärmt, falls, wie Sie sagten, die App-Domain entladen wird. An diesem Punkt scheint es, dass die App-Domain mehr entladen wird, als es sein sollte, und ich bin mir nicht sicher, warum, Recycling ist nur in der Nacht, Leerlauf ist auf 0 gesetzt.
Peter
4
Warum halten Sie das Lesen von Dummy-Daten für den falschen Ansatz?
Josh Heitzman
5
Es fühlt sich einfach nicht richtig an, ich dachte, es könnte etwas eleganteres geben, das mir nicht bewusst ist. Aber wenn dies die einzige Lösung ist und jemand mit guten Kenntnissen bestätigen kann, dass es keinen anderen Weg gibt, werde ich einfach damit weitermachen.
Peter
1
Ein Problem, das beim Herunterfahren des App-Pools nach einer Zeit ohne Aktivität (aufgrund von geringem Datenverkehr) aufgetreten ist, besteht darin, einen Dienst zu erstellen, der in einem festgelegten Zeitintervall eine Anforderung an eine Ihrer Seiten sendet. Dies verhindert die lange Verzögerung, bevor der App-Pool bei der ersten Anforderung neu gestartet wird. Oder Sie können einen kostenlosen Dienst wie www.pingalive.com verwenden, um Ihre Domain / IP zu pingen. Dies verhindert auch, dass Ihre zwischengespeicherten Objekte gelöscht werden, bevor sie abgelaufen sind.
Hatsrumandcode

Antworten:

55
  • Was wäre der beste Ansatz, um jederzeit eine hohe Verfügbarkeit in meinem Entity Framework zu haben?

Sie können eine Mischung aus vorgenerierten Ansichten und statisch kompilierten Abfragen auswählen.

Statische CompiledQuerys sind gut, weil sie schnell und einfach zu schreiben sind und zur Leistungssteigerung beitragen. Mit EF5 ist es jedoch nicht erforderlich, alle Ihre Abfragen zu kompilieren, da EF Abfragen selbst automatisch kompiliert. Das einzige Problem ist, dass diese Abfragen verloren gehen können, wenn der Cache durchsucht wird. Sie möchten also weiterhin Verweise auf Ihre eigenen kompilierten Abfragen für diejenigen enthalten, die nur sehr selten vorkommen, aber teuer sind. Wenn Sie diese Abfragen in statische Klassen einteilen, werden sie kompiliert, wenn sie zum ersten Mal benötigt werden. Dies kann für einige Abfragen zu spät sein. Daher möchten Sie möglicherweise die Kompilierung dieser Abfragen während des Anwendungsstarts erzwingen.

Vorgenerieren von Ansichten ist die andere Möglichkeit, wie Sie erwähnen. Insbesondere für Abfragen, deren Kompilierung sehr lange dauert und die sich nicht ändern. Auf diese Weise verschieben Sie den Leistungsaufwand von der Laufzeit zur Kompilierungszeit. Auch dies führt zu keiner Verzögerung. Aber diese Änderung wirkt sich natürlich auf die Datenbank aus, sodass es nicht so einfach ist, damit umzugehen. Code ist flexibler.

Verwenden Sie nicht viel TPT-Vererbung (dies ist ein allgemeines Leistungsproblem in EF). Bauen Sie Ihre Vererbungshierarchien weder zu tief noch zu weit auf. Nur 2-3 klassenspezifische Eigenschaften reichen möglicherweise nicht aus, um einen eigenen Typ zu erfordern, können jedoch als optionale (nullfähige) Eigenschaften für einen vorhandenen Typ behandelt werden.

Halten Sie sich nicht lange an einen einzelnen Kontext. Jede Kontextinstanz verfügt über einen eigenen Cache der ersten Ebene, der die Leistung verlangsamt, wenn er größer wird. Die Kontexterstellung ist billig, aber die Statusverwaltung innerhalb der zwischengespeicherten Entitäten des Kontexts kann teuer werden. Die anderen Caches (Abfrageplan und Metadaten) werden von verschiedenen Kontexten gemeinsam genutzt und sterben zusammen mit der AppDomain ab.

Alles in allem sollten Sie sicherstellen, dass Kontexte häufig zugewiesen und nur für kurze Zeit verwendet werden, dass Sie Ihre Anwendung schnell starten können, dass Sie selten verwendete Abfragen kompilieren und vorgenerierte Ansichten für leistungskritische und häufig verwendete Abfragen bereitstellen.

  • In welchen Fällen wird das Entity Framework wieder "kalt"? (Neukompilierung, Recycling, IIS-Neustart usw.)

Grundsätzlich jedes Mal, wenn Sie Ihre AppDomain verlieren. IIS führt alle 29 Stunden einen Neustart durch , sodass Sie niemals garantieren können, dass Ihre Instanzen vorhanden sind. Auch nach einiger Zeit ohne Aktivität wird die AppDomain heruntergefahren. Sie sollten versuchen, schnell wieder aufzutauchen. Möglicherweise können Sie einen Teil der Initialisierung asynchron durchführen (achten Sie jedoch auf Multithreading-Probleme). Sie können geplante Aufgaben verwenden, die Dummy-Seiten in Ihrer Anwendung aufrufen, wenn keine Anforderungen vorliegen, um das Absterben der AppDomain zu verhindern. Dies wird jedoch möglicherweise der Fall sein.

Ich gehe auch davon aus, dass es einen Neustart geben wird, wenn Sie Ihre Konfigurationsdatei oder die Assemblys ändern.

Andreas
quelle
Danke Andre, das war was ich brauchte.
Peter
@Andreas Selbst bei statisch kompilierten Abfragen ist der erste Lauf zu lang. Gibt es eine Möglichkeit, diese aufzuwärmen, außer: Dummy-Datenlesevorgänge beim Anwendungsstart durchführen, um die Modelle aufzuwärmen, zu generieren und zu validieren.
ManishKungwani
@Andreas Also braucht Entity Framework5 es oder nicht? Was ist anders, wenn es auf ef5 verwendet wird (ich meine immer noch langsam oder wenig Teig oder nicht anders?)
Qakmak
"Statische CompiledQuerys sind gut, weil sie schnell und einfach zu schreiben sind und zur Leistungsminderung beitragen." Reduzierte Leistung?
Mathemats
9

Wenn Sie nach maximaler Leistung für alle Anrufe suchen, sollten Sie Ihre Architektur sorgfältig prüfen. Beispielsweise kann es sinnvoll sein, häufig verwendete Suchvorgänge im Server-RAM vorab zwischenzuspeichern, wenn die Anwendung geladen wird, anstatt bei jeder Anforderung Datenbankaufrufe zu verwenden. Diese Technik gewährleistet minimale Antwortzeiten der Anwendung für häufig verwendete Daten. Sie müssen jedoch sicher sein, dass Sie eine gut verhaltene Ablaufrichtlinie haben, oder Ihren Cache immer leeren, wenn Änderungen vorgenommen werden, die sich auf die zwischengespeicherten Daten auswirken, um Probleme mit der Parallelität zu vermeiden.

Im Allgemeinen sollten Sie sich bemühen, verteilte Architekturen so zu entwerfen, dass nur E / A-basierte Datenanforderungen erforderlich sind, wenn die lokal zwischengespeicherten Informationen veraltet sind oder transaktional sein müssen. Das Abrufen von Datenanforderungen über das Kabel dauert normalerweise 10 bis 1000 Mal länger als das Abrufen eines lokalen Speichers im Speichercache. Diese eine Tatsache allein macht Diskussionen über "kalte vs. warme Daten" im Vergleich zum Problem "lokale vs. entfernte" Daten oft belanglos.

mcstar
quelle
Dies ist ein guter Punkt, den ich oft ignoriere, während ich über die Rohleistung des Entity-Frameworks gehypt werde. Ich werde dies weiter untersuchen und die Prinzipien des Caching genauer untersuchen. "Kalt gegen warm" in Bezug auf EF ist jedoch immer noch etwas, das ich besser verstehen möchte.
Peter
2
"Diese eine Tatsache allein macht Diskussionen über" kalte vs. warme Daten "im Vergleich zum Problem" lokale vs. entfernte "Daten oft belanglos." Nicht wirklich. Wenn Sie es nicht lokal zwischengespeichert haben (was Sie anfangs nicht tun werden), müssen Sie immer noch EF drücken und die Initialisierungsschmerzen erleiden, um Ihren Cache zu füllen. An denselben Stellen, an denen Ihr Cache nicht initialisiert ist, wird EF nicht initialisiert. Das Hinzufügen einer Caching-Ebene kann also nicht helfen, wenn das einzige Problem die EF-Initialisierungszeit ist, aber es wird eine weitere Komplexitätsebene hinzufügen ...
MikeJansen
8

Allgemeine Hinweise.

  • Führen Sie eine strenge Protokollierung durch, einschließlich des Zugriffs und der Anforderungszeit .
  • Führen Sie Dummy-Anforderungen aus, wenn Sie Ihre Anwendung initialisieren, um sehr langsame Warmstartanforderungen zu starten , die Sie aus dem vorherigen Schritt übernommen haben.
  • Optimieren Sie nicht, es sei denn, es handelt sich um ein echtes Problem. Kommunizieren Sie mit dem Verbraucher der Anwendung und fragen Sie. Machen Sie es sich mit einer kontinuierlichen Rückkopplungsschleife bequem, wenn Sie nur herausfinden möchten, was optimiert werden muss .

Erklären Sie nun, warum Dummy-Anfragen nicht der falsche Ansatz sind .

  • Weniger Komplexität - Sie erwärmen die Anwendung auf eine Weise, die unabhängig von Änderungen im Framework funktioniert, und Sie müssen möglicherweise keine funky APIs / Framework-Interna herausfinden, um sie richtig auszuführen .
  • Größere Abdeckung - Sie erwärmen alle Caching-Ebenen gleichzeitig, die mit der langsamen Anforderung zusammenhängen.

Erklären, wann ein Cache "kalt" wird.

Dies geschieht auf jeder Ebene in Ihrem Framework , die einen Cache anwendet. Eine gute Beschreibung finden Sie oben auf der Leistungsseite .

  • Wann immer ein Cache nach einer möglichen Änderung, die den Cache veraltet macht, validiert werden muss, kann dies eine Zeitüberschreitung oder eine intelligentere sein (dh eine Änderung des zwischengespeicherten Elements).
  • Wenn ein Cache-Element entfernt wird, wird der Algorithmus dafür im Abschnitt "Cache-Räumungsalgorithmus" in dem von Ihnen verknüpften Leistungsartikel beschrieben , jedoch kurz.
    • LFRU-Cache (am wenigsten häufig - kürzlich verwendet) für Trefferanzahl und Alter mit einem Limit von 800 Elementen.

Die anderen Dinge, die Sie erwähnt haben, insbesondere das Neukompilieren und Neustarten von IIS, löschen entweder Teile oder alle In-Memory-Caches.

udoprog
quelle
Dies ist eine weitere hilfreiche Antwort, die sehr geschätzt wird.
Peter
3

Verwenden Sie, wie bereits erwähnt, "vorgenerierte Ansichten", die wirklich alles sind, was Sie tun müssen.

Aus Ihrem Link extrahiert : "Wenn Ansichten generiert werden, werden sie auch validiert. Unter Leistungsgesichtspunkten ist die überwiegende Mehrheit der Kosten für die Generierung von Ansichten die Validierung der Ansichten."

Dies bedeutet, dass der Leistungsstoß auftritt, wenn Sie Ihre Modellbaugruppe bauen. Ihr Kontextobjekt überspringt dann die "kalte Abfrage" und bleibt für die Dauer des Lebenszyklus des Kontextobjekts sowie für nachfolgende neue Objektkontexte ansprechbar.

Das Ausführen irrelevanter Abfragen dient keinem anderen Zweck als dem Verbrauch von Systemressourcen.

Die Abkürzung ...

  1. Überspringen Sie die zusätzliche Arbeit vorgenerierter Ansichten
  2. Erstellen Sie Ihren Objektkontext
  3. Feuern Sie diese süße irrelevante Frage ab
  4. Behalten Sie dann für die Dauer Ihres Prozesses einfach einen Verweis auf Ihren Objektkontext bei (nicht empfohlen).
Hotpie
quelle
3
Überprüfen Sie Folgendes: Verwenden der T4-Vorlage zur Ansichtsgenerierung .
Kzfabi
2

Ich habe keine Erfahrung in diesem Rahmen. In anderen Kontexten, z. B. Solr, sind vollständig Dummy-Lesevorgänge nur dann von Nutzen, wenn Sie die gesamte Datenbank (oder den gesamten Index) zwischenspeichern können.

Ein besserer Ansatz wäre, die Abfragen zu protokollieren, die häufigsten aus den Protokollen zu extrahieren und sie zum Aufwärmen zu verwenden. Stellen Sie nur sicher, dass Sie die Aufwärmabfragen nicht protokollieren oder aus den Protokollen entfernen, bevor Sie fortfahren.

estani
quelle