Kolumne: Dino talks

Ausgabezwischenspeicherung (Output Caching)
Kommentare

Caching ist die Fähigkeit des Systems oder der Anwendung, häufig verwendete Daten auf einem Zwischenspeichermedium abzulegen. ASP.NET bringt zwei unabhängige Varianten mit, die sich allerdings nicht gegenseitig ausschließen – Caching von Anwendungsdaten und Caching der Ausgabe von bereitgestellten Seiten. ASP.NET stellt zum einen eine Rich API für die Programmierung bereit und bietet zum anderen einen leistungsfähigen Satz von Konfigurationseinstellungen. In diesem Artikel geht es um die Konfigurationseinstellungen, die für die Feinabstimmung der Caching-Funktionalität in ASP.NET Web Forms und ASP.NET MVC zur Verfügung stehen.

Sämtliche Caching-Funktionen des ASP.NET-Frameworks steuern Sie mit den Einstellungen im -Abschnitt der web.config-Datei Ihrer Anwendung. Der -Abschnitt besteht aus vier untergeordneten Abschnitten: cache, outputCache, outputCacheSettings und sqlCacheDependency. Der -Abschnitt definiert ein paar anwendungsweite Einstellungen wie den prozentualen Anteil des physischen Speichers, der für Caching reserviert werden soll. Die mit und benannten Abschnitte dienen dazu, das Verhalten des Ausgabe-Caches zu optimieren. Schließlich konfiguriert der sqlCacheDependency-Abschnitt die Abhängigkeit der zwischengespeicherten Elemente von Daten, die in einer SQL-Server-Datenbanktabelle gespeichert sind.

Der -Abschnitt

Der -Abschnitt hat das Schema in Listing 1, das die Eigenschaften und ihre Standardwerte angibt.

  

 

Die Eigenschaft disableMemoryCollection steuert das interne Flag, das das Cache-Modul anweist, nicht mehr verwendete Elemente über Bord zu werfen, um freien Speicher zu gewinnen. Wenn Sie den Standardwert für die Eigenschaft ändern und ihn auf true setzen, kann die Größe des von ASP.NET belegten Speichers nur noch wachsen. Praktisch erhält das System nur dann Speicher zurück, wenn Sie im Programm explizit spezifizieren, dass bestimmte Daten aus dem Cache zu entfernen sind. Es gibt keinen Automatismus, der sich um einen aufgeräumten Speicher kümmert, indem nicht verwendete Elemente entfernt werden.

Eine ähnliche Rolle spielt die Eigenschaft disableExpiration. Diese standardmäßig auf false gesetzte Eigenschaft steuert, ob das Cache-Modul die Ablaufrichtlinie für zwischengespeicherte Elemente unterstützt oder nicht. Im Allgemeinen unterstützt ASP.NET einige Ablaufrichtlinien – zeitbasiert (gleitend und absolut), dateibasiert und abhängig von Änderungen an verknüpften zwischengespeicherten Elementen. Und wenn Sie in diesem Fall die Eigenschaft auf true setzen, riskieren Sie Ausnahmen wegen Speichermangels, da der Umfang des vom Cache belegten Speichers potenziell über die Größe des physischen Speichers wachsen kann.

Die Eigenschaft privateBytesLimit gibt den Schwellenwert (in Byte) für Bedingungen mit großer Dringlichkeit an. Wird dieser Schwellenwert erreicht, intensiviert das Cache-System allmählich die Aufräummaßnahmen, um die Speicherbelegung zu verringern. Der Standardwert 0 für diese Eigenschaft bedeutet, dass ASP.NET anhand eigener Heuristiken ermittelt, wann mit dem Aufräumen von Daten zur Freigabe von Speicher begonnen wird. Als alternative Werte der Eigenschaft privateBytesLimit kommen Zahlen im Bereich von einigen Millionen Byte in Frage.

Mit percentagePhysicalMemoryUsedLimit lässt sich in alternativer Form definieren, wann das ASP.NET-System mit der Freigabe von Speicher beginnen sollte. Diese Eigenschaft gibt einen Grenzwert an, bis zu dem die Speicherbelegung als tolerierbar gilt. Der Wert drückt den prozentualen Anteil bezogen auf den gesamten physischen Speicher aus. Der belegte Speicher umfasst sowohl den für den Cache reservierten als auch den für andere Aufgaben verwendeten Speicher. Genau wie bei privateBytesLimit bedeutet der Wert 0, dass ASP.NET mit eigenen internen Algorithmen bestimmt, wann der Speicherdruck zu hoch ist.

Schließlich enthält die Eigenschaft privateBytesPollTime das Zeitintervall zwischen zwei aufeinanderfolgenden Prüfungen der Speicherauslastung. Das standardmäßige Abrufintervall beträgt zwei Minuten.

 

Der -Abschnitt

Die Ausgabezwischenspeicherung von ASP.NET-Seiten ist das Feature, mit dem Sie Seitenantworten zwischenspeichern können, sodass sich folgende Anforderungen ohne Ausführung der Seite bedienen lassen, indem einfach die zwischengespeicherte Ausgabe zurückgegeben wird. Ausgabezwischenspeicherung findet auf zwei Ebenen statt: gesamte Seiten oder Teile der Seite. Das Zwischenspeichern einer Seite arbeitet intelligent, sodass Sie gezielt Ausgaben abhängig vom anfordernden URL, der Abfragezeichenfolge, den Formularparametern und sogar benutzerdefinierten Zeichenfolgen speichern können. Parameter für das Zwischenspeichern von Ausgaben lassen sich an allen erforderlichen Stellen mithilfe der @OutputCache-Direktive in ASP.NET-Web-Forms-Seiten und mit dem OutputCache-Attribut in ASP.NET MVC spezifizieren. Außerdem können Sie sie dauerhaft in der Konfigurationsdatei der Anwendung konfigurieren. Wenn Sie sich für die zweite Option entscheiden, müssen Sie den -Abschnitt bearbeiten. Der -Abschnitt kümmert sich um das Zwischenspeichern der Ausgabe. Das Schema des Abschnitts sieht mit Standardwerten wie in Listing 2 aus.


  

 

Wenn in der Konfigurationsdatei Ausgabe- oder Fragmentzwischenspeicherung deaktiviert ist, werden weder Seiten noch Benutzersteuerelemente zwischengespeichert, unabhängig von den per Programm festgelegten Einstellungen. Die Eigenschaften hinter diesem Aspekt sind enableOutputCache und enableFragmentCache. Beide sind standardmäßig auf true gesetzt.

Das Attribut sendCacheControlHeader zeigt an, ob der cache-control:private Header vom Ausgabe-Cache-Modul standardmäßig gesendet wird. Analog aktiviert bzw. deaktiviert das omitVaryStar-Attribut einen HTTP Vary:* Header in der Antwort. Das Attribut enableKernelCacheForVaryByStar steuert, ob Kernel-Zwischenspeicherung aktiviert ist. Die Kernel-Zwischenspeicherung wird nur für komprimierte Antworten unterstützt. Das heißt, dass unabhängig vom Wert des Attributs die Kernel-Zwischenspeicherung immer dann nicht greift, wenn der Client eine unkomprimierte Antwort anfordert.

Das Attribut defaultProvider bezeichnet die Komponente, die sich um das Speichern und Bedienen der zwischengespeicherten Ausgabe für eingehende Anforderungen kümmert. Der Standardprovider basiert auf dem gleichen Code wie Ausgabezwischenspeicherung in früheren Versionen von ASP.NET. Der Speicherplatz befindet sich im speicherinternen Cache. Der AspNetInternalProvider-Providername stimmt eigentlich mit keiner Klasse in der Assembly system.web überein. Er ist lediglich ein Pseudonym, der das System anweist, mit der integrierten Logik auszukommen, die für alle vorherigen Versionen von ASP.NET funktioniert hat.

Indem Sie Ihren eigenen Provider schreiben, können Sie die Speicherung des Ausgabe-Caches ändern. Die neue abstrakte Klasse OutputCacheProvider des Frameworks dient Ihnen als Ausgangspunkt, um benutzerdefinierte Provider für Ausgabe-Caches zu erstellen.

 

Einstellungen für den Ausgabe-Cache

Der -Abschnitt enthält eine Gruppe von Cache-Einstellungen, die sich über die @OutputCache-Direktive auf Seiten anwenden lassen. Der Abschnitt enthält nur einen untergeordneten Abschnitt namens . Ein Profil für den Ausgabe-Cache ist einfach eine Möglichkeit, auf mehrere Einstellungen unter einem einzigen Namen zu verweisen (Listing 3).


  
    
  
  

 

In diesem Beispiel definiert das ServerOnly-Profil eine Verweildauer im Cache von 60 Sekunden und speichert unterschiedliche Versionen der Seite abhängig vom jeweiligen Browsertyp. Das Schema von ist in Listing 4 zu sehen.


   
  

 

Profile für den Ausgabe-Cache haben vor allem die Aufgabe, eine einfache Möglichkeit zu realisieren, ein ganzes Bündel von Cache-bezogenen Einstellungen auf eine potenziell große Anzahl von Seiten und Benutzersteuerelementen anzuwenden, ohne immer wieder die gleichen Einstellungen an den unterschiedlichsten Stellen schreiben, bearbeiten und verwalten zu müssen.

 

Der -Abschnitt

Eine Datenbankabhängigkeit ist ein spezieller Fall einer Cache-Abhängigkeit, die aus dem automatischen Ungültigmachen bestimmter zwischengespeicherter Daten besteht, wenn sich der Inhalt der Quelldatenbanktabelle ändert. In ASP.NET wird dieses Feature über die vom System bereitgestellte Klasse SqlCacheDependency implementiert. Der -Abschnitt definiert die Einstellungen, auf die die Klasse SqlCacheDependency zurückgreift, wenn Datenbankzwischenspeicherung und tabellenbasiertes Abfragen gegen Versionen von Microsoft SQL Server ab einschließlich Version 7.0 verwendet werden (Listing 5).


   
      
   
  

 

Das Attribut pollTime gibt das Abfrageintervall in Millisekunden an. Im obigen Beispiel wird jede überwachte Tabelle im Abstand von jeweils einer Sekunde überprüft. Unter dem -Knoten finden Sie einen Verweis auf überwachte Datenbanken. Das name-Attribut dient lediglich dazu, die Abhängigkeit zu benennen. Das Attribut connectionStringName zeigt auf einen Eintrag im -Abschnitt der web.config-Datei und gibt die Verbindungszeichenfolge für den Datenbankzugriff an. Wichtig dabei ist, dass zwar die SQL-Cache-Abhängigkeit mit allen Versionen von SQL Server ab Version 7 aufwärts funktioniert, der -Abschnitt jedoch ignoriert wird, wenn SqlCacheDependency in Verbindung mit SQL Server 2005 und neueren Versionen verwendet wird.

Zusammenfassung

Ausgabezwischenspeicherung von Seiten ist eine einfache Möglichkeit dafür, dass die Anwendung mehr Seiten schneller bedienen kann. Dieses Feature hat nichts mit ausgeklügelten Cache-Strategien oder elegantem Codeentwurf zu tun. Mit anderen Worten: Es versetzt Ihre Anwendung in die Lage, Seiten schneller zu bedienen, doch es macht die Anwendung nicht unbedingt effizienter und skalierbarer.

Außerdem sollten Sie sich bewusst sein, dass bei Anwendungen, die unter IIS 6 oder IIS 7 laufen, die Ausgabezwischenspeicherung von Seiten im klassischen Modus nur für anonyme Inhalte funktioniert. In der Tat werden Anforderungen nach zwischengespeicherten Seiten durch diese Versionen von IIS direkt bedient. Das heißt, dass die Anforderung niemals die Stufe in der ASP.NET-Pipeline erreicht, wo sie authentifiziert werden kann. Wenn die Anwendung dagegen für den integrierten Modus unter IIS 7.x konfiguriert ist, existiert eine einzelne Pipeline, die IIS und ASP.NET gemeinsam nutzen, und alle Anforderungen werden zuerst authentifiziert und dann auf zwischengespeicherte Ausgaben hin überprüft.

Dino Esposito ist R&D Director bei Crionet, einer Firma, die sich auf webbasierte Lösungen für Sportereignisse in ganz Europa spezialisiert hat (http://www.e-tennis.net). Außerdem ist Dino der Autor von „Programming ASP.NET MVC“, Microsoft Press, 2010.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -