Kapitel 4. Massiv skalierbares Content Caching
Diese Arbeit wurde mithilfe von KI übersetzt. Wir freuen uns über dein Feedback und deine Kommentare: translation-feedback@oreilly.com
4.0 Einleitung
Caching beschleunigt die Bereitstellung von Inhalten, indem es die Antworten speichert, um sie in Zukunft erneut bereitzustellen. Durch die Bereitstellung aus dem Cache entlastet NGINX die vorgelagerten Server, indem es ihnen teure, sich wiederholende Aufgaben abnimmt. Caching erhöht die Leistung und reduziert die Last, sodass du mit weniger Ressourcen schneller bedienen kannst. Caching reduziert außerdem die Zeit und Bandbreite, die für die Bereitstellung von Ressourcen benötigt wird.
Die Skalierung und Verteilung von Caching-Servern an strategischen Standorten kann einen dramatischen Einfluss auf die Nutzererfahrung haben. Für die beste Leistung ist es optimal, die Inhalte in der Nähe des Nutzers zu hosten . Du kannst deine Inhalte auch in der Nähe deiner Nutzer/innen zwischenspeichern. Das ist das Muster der Content Delivery Networks, oder CDNs. Mit NGINX kannst du deine Inhalte überall dort zwischenspeichern, wo du einen NGINX-Server platzieren kannst, so dass du dein eigenes CDN erstellen kannst. Mit dem NGINX-Caching kannst du auch passiv cachen und im Falle eines Upstream-Ausfalls zwischengespeicherte Antworten ausliefern. Die Caching-Funktionen sind nur im Kontext von http
verfügbar. Dieses Kapitel behandelt die Caching- und Content-Delivery-Funktionen von NGINX.
4.1 Caching-Zonen
Problem
Du musst Inhalte zwischenspeichern und festlegen, wo der Cache gespeichert wird.
Lösung
Verwende die proxy_cache_path
Direktive, um Shared-Memory-Cache-Zonen und einen Speicherort für den Inhalt zu definieren:
proxy_cache_path
/
var
/
nginx
/
cache
keys_zone
=
main_content
:
60
m
levels
=
1
:
2
inactive
=
3
h
max_size
=
20
g
min_free
=
500
m
;
proxy_cache
CACHE
;
Das Beispiel für die Cache-Definition erstellt ein Verzeichnis für zwischengespeicherte Antworten im Dateisystem unter /var/nginx/cache und einen gemeinsamen Speicherbereich namens main_content
mit 60 MB Speicherplatz. In diesem Beispiel werden die Ebenen der Verzeichnisstruktur festgelegt, das Auslagern von zwischengespeicherten Antworten definiert, nachdem sie drei Stunden lang nicht angefordert wurden, und eine maximale Größe des Caches von 20 GB definiert. Der Parameter min_free
weist NGINX an, wie viel Speicherplatz auf der max_size
freigehalten werden soll, bevor die gecachten Ressourcen entfernt werden. Die Direktive proxy_cache
weist einen bestimmten Kontext an, die Cache-Zone zu nutzen. Die Direktive proxy_cache_path
gilt für den Kontext http
und die Direktive proxy_cache
gilt für die Kontexte http
, server
und location
.
Diskussion
Um das Caching in NGINX zu konfigurieren, musst du einen Pfad und eine Zone angeben, die verwendet werden sollen. Eine Cache-Zone in NGINX wird mit der Direktive proxy_cache_path
erstellt. Die Direktive proxy_cache_path
legt einen Speicherort für die zwischengespeicherten Informationen und einen gemeinsamen Speicherbereich für aktive Schlüssel und Antwortmetadaten fest. Optionale Parameter für diese Direktive bieten mehr Kontrolle darüber, wie der Cache verwaltet und auf ihn zugegriffen wird.
Der Parameter levels
legt fest, wie die Verzeichnisstruktur erstellt wird. Der Wert ist eine durch Doppelpunkte getrennte Liste von Zahlen, die die Länge der aufeinander folgenden Unterverzeichnisnamen festlegt. Tiefere Strukturen helfen zu vermeiden, dass zu viele gecachte Dateien in einem einzigen Verzeichnis auftauchen. NGINX speichert dann das Ergebnis in der angegebenen Dateistruktur, wobei der Cache-Schlüssel als Dateipfad verwendet wird und die Verzeichnisse anhand des Wertes levels
aufgeteilt werden.
Mit dem Parameter inactive
kannst du festlegen, wie lange ein Cache-Element nach seiner letzten Nutzung gespeichert werden soll. Auch die Größe des Caches kann mit dem Parameter max_size
eingestellt werden. Andere Parameter beziehen sich auf den Cache-Ladevorgang, bei dem die Cache-Schlüssel aus den auf der Festplatte zwischengespeicherten Dateien in die gemeinsame Speicherzone geladen werden, sowie auf viele andere Optionen. Weitere Informationen über die Direktive proxy_cache_path
findest du in der Dokumentation im Abschnitt "Siehe auch" .
Siehe auch
4.2 Hash-Schlüssel zwischenspeichern
Lösung
Verwende die proxy_cache_key
Direktive zusammen mit Variablen, um zu definieren, was ein Cache-Treffer oder -Miss ist:
proxy_cache_key
"$host$request_uri $cookie_user"
;
Dieser Cache-Hash-Schlüssel weist NGINX an, Seiten auf der Grundlage des Hosts und der angeforderten URI sowie eines Cookies, das den Benutzer definiert, zwischenzuspeichern. So kannst du dynamische Seiten zwischenspeichern, ohne dass Inhalte angezeigt werden, die für einen anderen Nutzer erstellt wurden.
Diskussion
Der Standardwert proxy_cache_key
, der für die meisten Anwendungsfälle geeignet ist, lautet "$scheme$proxy_host$request_uri"
. Zu den verwendeten Variablen gehören das Schema (http
oder https
), proxy_host
, wohin die Anfrage gesendet wird, und die Anfrage-URI. Alles zusammen ergibt die URL, an die NGINX die Anfrage weiterleitet. Möglicherweise gibt es noch viele andere Faktoren, die eine eindeutige Anfrage pro Anwendung definieren, z. B. Anfrageargumente, Header, Sitzungskennungen usw., für die du einen eigenen Hash-Schlüssel erstellen möchtest.1
Die Auswahl eines guten Hash-Schlüssels ist sehr wichtig und sollte mit Blick auf die Anwendung gut durchdacht sein. Die Auswahl eines Cache-Schlüssels für statische Inhalte ist in der Regel recht einfach; die Verwendung des Hostnamens und der URI ist ausreichend. Die Auswahl eines Cache-Schlüssels für relativ dynamische Inhalte, wie z. B. Seiten für eine Dashboard-Anwendung, erfordert mehr Wissen darüber, wie die Nutzer mit der Anwendung interagieren und wie unterschiedlich die Erfahrungen der Nutzer sind. Bei der Zwischenspeicherung dynamischer Inhalte ist die Verwendung von Sitzungskennungen wie Cookies oder JWT-Tokens besonders nützlich. Aus Sicherheitsgründen möchtest du vielleicht nicht, dass zwischengespeicherte Daten von einem Nutzer zu einem anderen weitergegeben werden, ohne den Kontext vollständig zu verstehen. Die Direktive proxy_cache_key
konfiguriert die zu hashende Zeichenkette für den Cache-Schlüssel. Die Direktive proxy_cache_key
kann im Kontext der Blöcke http
, server
und location
gesetzt werden und bietet so eine flexible Kontrolle darüber, wie Anfragen gecached werden.
4.3 Cache-Sperren
Lösung
Mit der Direktive proxy_cache_lock
kannst du sicherstellen, dass immer nur eine Anfrage in den Cache geschrieben werden kann, während nachfolgende Anfragen darauf warten, dass die Antwort in den Cache geschrieben und von dort serviert wird:
proxy_cache_lock
on
;
proxy_cache_lock_age
10
s
;
proxy_cache_lock_timeout
3
s
;
Diskussion
Wir wollen keine Anfragen weiterleiten, bei denen frühere Anfragen für denselben Inhalt noch im Umlauf sind und gerade in den Cache geschrieben werden. Die Direktive proxy_cache_lock
weist NGINX an, Anfragen zurückzuhalten, die für eine Ressource im Cache bestimmt sind, die gerade aufgefüllt wird. Die Proxy-Anfrage, die den Cache auffüllt, hat nur eine begrenzte Zeitspanne, bevor eine andere Anfrage versucht, die Ressource aufzufüllen. Dies wird durch die Direktive proxy_cache_lock_age
festgelegt, die standardmäßig fünf Sekunden beträgt. NGINX kann auch zulassen, dass Anfragen, die eine bestimmte Zeit gewartet haben, an den Proxy-Server weitergeleitet werden, der dann nicht versucht, den Cache zu füllen. Dies wird mit der Direktive proxy_cache_lock_timeout
festgelegt, die ebenfalls auf fünf Sekunden eingestellt ist. Du kannst dir proxy_cache_lock_age
und proxy_cache_lock_timeout
wie folgt vorstellen: "Du brauchst zu lange, ich fülle den Cache für dich auf" bzw. "Du brauchst zu lange, um zu warten, ich hole mir, was ich brauche und lasse dich den Cache in deiner eigenen Zeit auffüllen".
4.4 Stale Cache verwenden
Diskussion
Die Fähigkeit von NGINX, veraltete Cache-Ressourcen auszuliefern, während deine Anwendung nicht korrekt zurückkehrt, kann wirklich den Tag retten. Diese Funktion kann dem Endnutzer die Illusion eines funktionierenden Webdienstes vermitteln, während das Backend möglicherweise nicht erreichbar ist. Die Bereitstellung aus dem Stale-Cache verringert außerdem die Belastung deiner Backend-Server, wenn es zu Problemen kommt, was wiederum dem Entwicklungsteam etwas Spielraum zur Fehlerbehebung verschafft.
Die Konfiguration weist NGINX an, veraltete Cache-Ressourcen zu verwenden, wenn die Upstream-Anfrage eine Zeitüberschreitung aufweist, einen invalid_header
-Fehler liefert oder Antwortcodes der Stufen 400 und 500 zurückgibt. Die Parameter error
und updating
sind ein wenig speziell. Der Parameter error
erlaubt die Verwendung des Stale-Cache, wenn kein Upstream-Server ausgewählt werden kann. Mit dem Parameter updating
wird NGINX angewiesen, veraltete Cache-Ressourcen zu verwenden, während der Cache mit neuen Inhalten aktualisiert wird.
4.5 Cache-Umgehung
Lösung
Verwende die Direktive proxy_cache_bypass
mit einem Wert, der nicht leer oder ungleich Null ist. Eine Möglichkeit, dies dynamisch zu tun, besteht darin, eine Variable in einem location
Block, der nicht gecacht werden soll, auf einen anderen Wert als einen leeren String oder 0 zu setzen:
proxy_cache_bypass
$
http_cache_bypass
;
Die Konfiguration weist NGINX an, den Cache zu umgehen, wenn der HTTP-Request-Header namens cache_bypass
auf einen Wert ungleich 0 gesetzt wird. In diesem Beispiel wird ein Header als Variable verwendet, um zu bestimmen, ob das Caching umgangen werden soll - der Kunde muss diesen Header für seine Anfrage selbst setzen.
Diskussion
Es gibt eine Reihe von Szenarien, die erfordern, dass die Anfrage nicht im Cache gespeichert wird. Hierfür stellt NGINX die Direktive proxy_cache_bypass
zur Verfügung. Wenn der Wert nicht leer oder ungleich Null ist, wird die Anfrage an einen vorgelagerten Server gesendet und nicht aus dem Cache gezogen. Die verschiedenen Anforderungen und Szenarien für die Umgehung des Caches hängen vom Anwendungsfall deiner Anwendung ab. Die Techniken zur Umgehung des Caches können so einfach sein wie die Verwendung eines Request- oder Response-Headers oder so kompliziert wie das Zusammenspiel mehrerer map
Blöcke.
Es gibt viele Gründe, warum du den Cache umgehen möchtest, z. B. bei der Fehlersuche oder beim Debuggen. Es kann schwierig sein, Probleme zu reproduzieren, wenn du ständig Seiten aus dem Cache abrufst oder wenn dein Cache-Schlüssel an eine bestimmte Benutzerkennung gebunden ist. Die Möglichkeit, den Cache zu umgehen, ist wichtig. Zu den Optionen gehört unter anderem, den Cache zu umgehen, wenn ein bestimmtes Cookie, ein Header oder ein Anfrageargument gesetzt ist. Du kannst den Cache für einen bestimmten Kontext, z. B. einen location
Block, auch komplett ausschalten, indem du proxy_cache off;
setzt.
4.6 Cache-Löschung mit NGINX Plus
Problem
Du musst ein Objekt aus dem Cache ungültig machen.
Lösung
Verwende die Funktion purge von NGINX Plus, die Direktive proxy_cache_purge
und eine nicht leere oder nullwertige Variable:
map
$
request_method
$
purge_method
{
PURGE
1
;
default
0
;
}
server
{
# ...
location
/
{
# ...
proxy_cache_purge
$
purge_method
;
}
}
In diesem Beispiel wird der Cache für ein bestimmtes Objekt geleert, wenn es mit der Methode PURGE
angefordert wird. Das folgende curl
Beispiel zeigt, wie der Cache einer Datei namens main.js geleert wird:
$ curl -X PURGE http://www.example.com/main.js
Diskussion
Eine gängige Methode, um statische Dateien zu verwalten, ist es, einen Hash der Datei in den Dateinamen aufzunehmen. Dadurch wird sichergestellt, dass dein CDN neue Inhalte und Codes als neue Dateien erkennt, weil sich der URI geändert hat. Bei dynamischen Inhalten, für die du Cache-Schlüssel festgelegt hast, die nicht zu diesem Modell passen, funktioniert das jedoch nicht. In jedem Caching-Szenario musst du eine Möglichkeit haben, den Cache zu löschen.
NGINX Plus bietet eine einfache Methode zum Löschen von gecachten Antworten. Die Direktive proxy_cache_purge
bereinigt die gecachten Einträge, die der Anfrage entsprechen, wenn der Wert Null oder ein nicht leerer Wert übergeben wird. Eine einfache Möglichkeit, die Bereinigung einzurichten, ist das Mapping der Anfragemethode für PURGE
. Du solltest dies jedoch in Verbindung mit dem Modul geoip
oder einer einfachen Authentifizierung verwenden, um sicherzustellen, dass nicht jeder deine wertvollen Cache-Elemente bereinigen kann. NGINX hat auch die Verwendung von *
ermöglicht, das Cache-Elemente löscht, die mit einem gemeinsamen URI-Präfix übereinstimmen. Um Wildcards zu verwenden, musst du deine Direktive proxy_cache_path
mit dem Argument purger=on
konfigurieren.
Siehe auch
4.7 Cache Slicing
Lösung
Verwende die NGINX slice
Direktive und ihre eingebetteten Variablen, um das Cache-Ergebnis in Fragmente zu unterteilen:
proxy_cache_path
/
tmp
/
mycache
keys_zone
=
mycache
:
10
m
;
server
{
# ...
proxy_cache
mycache
;
slice
1
m
;
proxy_cache_key
$
host
$
uri
$
is_args
$
args
$
slice_range
;
proxy_set_header
Range
$
slice_range
;
proxy_http_version
1.1
;
proxy_cache_valid
200
206
1
h
;
location
/
{
proxy_pass
http
:
//
origin
:
80
;
}
}
Diskussion
Diese Konfiguration definiert eine Cache-Zone und aktiviert sie für den Server. Mit der Direktive slice
wird NGINX dann angewiesen, die Antwort in 1 MB große Dateisegmente zu zerlegen . Die zwischengespeicherten Ressourcen werden gemäß der Direktive proxy_cache_key
gespeichert. Beachte die eingebettete Variable mit dem Namen slice_range
. Dieselbe Variable wird als Header bei der Anfrage an den Ursprung verwendet, und die HTTP-Version der Anfrage wird auf HTTP/1.1 hochgestuft, da 1.0 keine Byte-Range-Anfragen unterstützt. Die Cache-Gültigkeit wird für Antwortcodes von 200
oder 206
für eine Stunde festgelegt, und dann werden der Standort und der Ursprung definiert.
Das Cache-Slice-Modul wurde für die Auslieferung von HTML5-Videos entwickelt, die Byte-Range-Anfragen verwenden, um Inhalte als Pseudostream an den Browser zu senden. Standardmäßig ist NGINX in der Lage, Byte-Range-Anfragen aus seinem Cache zu bedienen. Wenn eine Anfrage für einen Bytebereich für nicht gecachte Inhalte gestellt wird, fordert NGINX die gesamte Datei vom Ursprung an. Wenn du das Cache-Slice-Modul verwendest, fordert NGINX nur die erforderlichen Segmente vom Ursprung an. Bereichsanfragen, die größer als die Slice-Größe sind und die gesamte Datei umfassen, lösen Unteranfragen für jedes der benötigten Segmente aus, die dann zwischengespeichert werden. Wenn alle Segmente im Cache sind, wird die Antwort zusammengestellt und an den Client gesendet. So kann NGINX Inhalte, die in Bereichen angefordert werden, effizienter im Cache speichern und bereitstellen.
Das Cache-Slice-Modul sollte nur für große Ressourcen verwendet werden, die sich nicht ändern. NGINX validiert den ETag jedes Mal, wenn es ein Segment vom Ursprung erhält. Wenn sich der ETag auf der Ursprungsseite ändert, bricht NGINX die Cache-Population des Segments ab, da der Cache nicht mehr gültig ist. Wenn sich der Inhalt ändert und die Datei kleiner ist oder dein Ursprung mit Lastspitzen während des Cache-Füllvorgangs umgehen kann, ist es besser, die in Rezept 4.3 beschriebene Direktive cache_lock
zu verwenden. Mehr über Cache-Slicing-Techniken erfährst du in dem Blog, der im Abschnitt "Siehe auch" aufgeführt ist .
1 Jede beliebige Kombination von Text oder Variablen, die NGINX zur Verfügung stehen, kann als Cache-Schlüssel verwendet werden. Eine Liste der Variablen ist in NGINX verfügbar.
Get NGINX Kochbuch, 3. Auflage now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.