Wir haben eine datengesteuerte ASP.NET-Website, die mit dem Standardmuster für Daten-Caching (hier von MSDN angepasst) geschrieben wurde:
%Vor%Das Problem dabei ist, dass der Aufruf von GetDataFromSQL () teuer ist und die Nutzung der Site ziemlich hoch ist. Alle fünf Minuten, wenn der Cache gelöscht wird, wird die Site sehr "sticky", während viele Anfragen darauf warten, dass die neuen Daten abgerufen werden.
Was wir wirklich wollen, ist, dass die alten Daten aktuell bleiben, während neue Daten periodisch im Hintergrund neu geladen werden. (Die Tatsache, dass jemand Daten sieht, die sechs Minuten alt sind, ist also kein großes Problem - die Daten sind nicht das zeitsensitiv). Dies ist etwas, das ich selbst schreiben kann, aber es wäre nützlich zu wissen, ob alternative Caching-Engines (ich kenne Namen wie Velocity, Memcache) diese Art von Szenario unterstützen. Oder fehlt mir ein offensichtlicher Trick mit dem Standard-ASP.NET-Datencache?
Sie sollten den CacheItemUpdateCallback
-Delegaten verwenden können, der der 6. Parameter ist, der die 4. Überladung für Insert
unter Verwendung von ASP.NET Cache ist:
Folgendes sollte funktionieren:
%Vor%Von MSDN :
Wenn ein Objekt im Cache abläuft, ASP.NET ruft den CacheItemUpdateCallback-Methode mit der Schlüssel für den Cache-Gegenstand und die Grund, den Sie vielleicht aktualisieren möchten Artikel. Die restlichen Parameter davon Methode sind out-Parameter. Sie liefern das neue zwischengespeicherte Element und optional Ablauf- und Abhängigkeitswerte zu Verwenden Sie diese Option, wenn Sie das zwischengespeicherte Objekt aktualisieren.
Der Update-Callback wird nicht aufgerufen, wenn Das zwischengespeicherte Objekt wird explizit entfernt durch einen Aufruf von Remove ().
Wenn Sie möchten, dass das zwischengespeicherte Objekt gespeichert wird aus dem Cache entfernt, müssen Sie Gibt im teurObject null zurück Parameter. Andernfalls geben Sie a zurück Verweis auf die neuen zwischengespeicherten Daten von Verwenden des teurlyObject-Parameters. Wenn Sie kein Ablaufdatum angeben oder Abhängigkeitswerte wird der Artikel sein nur aus dem Cache entfernt Speicher wird benötigt.
Wenn die Callback-Methode ein Ausnahme unterdrückt ASP.NET die Ausnahme und entfernt die zwischengespeicherte Wert.
Ich habe das nicht getestet, so dass Sie vielleicht ein bisschen daran herumbasteln müssen, aber es sollte Ihnen die Grundidee dessen geben, was Sie erreichen wollen.
Ich kann sehen, dass es eine potentielle Lösung dafür gibt, die AppFabric verwendet (der Cache, früher bekannt als Velocity), damit Sie ein gecachtes Objekt sperren können es kann aktualisiert werden. Während ein Element gesperrt ist, funktionieren gewöhnliche (nicht verriegelnde) Get-Anfragen weiterhin normal und geben die aktuelle Kopie des Objekts zurück.
Wenn Sie so vorgehen, können Sie auch Ihre GetDataFromSQL
-Methode von einem anderen Prozess trennen, z. B. von einem Windows-Dienst, der alle fünf Minuten ausgeführt wird. Dies sollte Ihre "sticky" -Seite mindern.
Oder ...
Anstatt nur die Daten für jeweils fünf Minuten gleichzeitig zwischenzuspeichern, sollten Sie eine SqlCacheDependency -Objekt, wenn Sie die Daten in den Cache stellen, sodass sie nur aktualisiert werden, wenn sich die Daten tatsächlich ändern. Auf diese Weise können Sie die Daten für längere Zeit zwischenspeichern, so dass Sie eine bessere Leistung erhalten und immer die aktuellen Daten anzeigen.
(BTW, oberer Tipp, um Ihre Absicht klarer zu machen, wenn Sie Objekte in den Cache stellen - der Cache verfügt über eine NoSlidingExpiration
(und eine NoAbsoluteExpiration
) Konstante, die besser lesbar ist als Ihre Timespan.Zero)
Fügen Sie zuerst das Datum, das Sie tatsächlich benötigen, in eine schlanke Klasse (auch bekannt als POCO) statt dieses DataTable-Schwein ein.
Zweitens, benutze Cache und Hash - damit, wenn deine Zeitabhängigkeit abläuft, du einen Async-Delegaten spawnen kannst, um neue Daten zu holen, aber deine alten Daten sind noch sicher in einer separaten Hash-Tabelle (nicht Dictionary - es ist nicht sicher für Multi-Reader Single-Writer-Threading).
Abhängig von der Art der Daten und der Zeit / dem Budget, um die SQL-Seite neu zu strukturieren, könnten Sie möglicherweise nur Dinge holen, die LastWrite jünger als Ihr Update-Fenster haben. Du wirst ein 2-stufiges Update benötigen (du musst Dats aus dem Hash-gespeicherten Opjekt in ein neues Objekt kopieren - Zeug in Hash ist streng read-only für jede Verwendung oder die Hölle wird losbrechen).
Oh und SqlCacheDependency ist berüchtigt dafür, unzuverlässig zu sein und kann Ihr System in verrückte Updates verwandeln.