Cache-Warmup-Strategien nach Deployments in Magento
AI generated
SET
TTL
Redis · Magento · Deployment · Performance
Cache-Warmup-Strategien nach Deployments in Magento
Vom kalten Redis-Cache zur stabilen ersten Minute

Nach jedem Magento-Deployment ist der Redis-Cache leer, und die ersten Requests treffen die Datenbank ungebremst. Dieser Artikel zeigt, warum dieser Traffic-Spike entsteht, wie Warmup-Crawler und Cache-Preload-Skripte ihn verhindern, und wie sich Warmup sauber in die Deployment-Pipeline integrieren laesst.

17 Min. Lesezeit Cache Warmup · Crawler · Preload · CI/CD Redis 7.x · Magento 2.4.8

1. Das Problem: kalter Cache nach dem Deployment

Jedes Magento-Deployment, das bin/magento cache:flush ausfuehrt oder den Konfigurationscache neu generiert, leert den Redis-Objektcache und haeufig auch den Full-Page-Cache. Der erste Request auf jede Kategorie- oder Produktseite nach dem Deployment trifft dann nicht mehr auf einen gefuellten Cache, sondern muss die komplette Seite neu rendern: Produktdaten aus MySQL laden, Preise berechnen, Layout zusammenbauen und erst am Ende das Ergebnis in Redis ablegen. Diese Cold-Start-Requests dauern oft das Zehn- bis Zwanzigfache eines Cache-Hits.

Bei niedrigem Traffic faellt dieser Effekt kaum auf, weil sich die Cache-Fuellung langsam ueber die ersten Minuten nach dem Deployment verteilt. Bei Shops mit konstant hohem Traffic oder waehrend einer Kampagne ist das Bild ein anderes: innerhalb von Sekunden treffen hunderte oder tausende Requests gleichzeitig auf denselben leeren Redis-Cache, und jeder einzelne davon loest eine eigene, vollstaendige Datenbankabfrage aus. Das Ergebnis ist ein kurzzeitiger, aber massiver Lastspitze auf der Datenbank, die im schlimmsten Fall zu Timeouts oder sogar zu einem kompletten Ausfall fuehrt, genau in dem Moment, in dem ein Deployment eigentlich unauffaellig ablaufen sollte.

Der Kern des Problems liegt darin, dass ein leerer Redis-Cache und echter Nutzer-Traffic gleichzeitig aufeinandertreffen. Cache-Warmup loest dieses Problem, indem der Cache proaktiv gefuellt wird, bevor echte Nutzer die Seite aufrufen, sodass die Datenbank die Last kontrolliert und sequenziell statt schlagartig und parallel abbekommt.

2. Thundering Herd: wenn viele Requests gleichzeitig laden

Der technische Fachbegriff fuer das beschriebene Phaenomen ist Thundering Herd: viele gleichzeitige Anfragen erkennen alle denselben fehlenden Cache-Eintrag und starten parallel dieselbe teure Berechnung, obwohl nur eine einzige Berechnung noetig waere. Ohne Schutzmechanismus fuehrt eine populaere Produktseite nach dem Deployment dazu, dass zehn oder mehr parallele PHP-Prozesse gleichzeitig dieselben Produktdaten aus der Datenbank laden, dieselbe Preisberechnung durchfuehren und am Ende alle denselben Wert in Redis schreiben.

Magentos Full-Page-Cache-Layer mit Redis als Backend bietet von Haus aus keinen vollstaendigen Schutz vor diesem Effekt, wenn viele Requests im selben Millisekunden-Fenster eintreffen. Ein wirksames Gegenmittel ist ein Lock-Mechanismus auf Anwendungsebene: der erste Request, der einen Cache-Miss feststellt, setzt einen kurzlebigen Lock-Key in Redis mit SET key value NX EX 5, berechnet den Wert und gibt den Lock danach frei. Weitere Requests, die denselben Lock vorfinden, warten kurz oder liefern eine leicht veraltete Version aus, statt die teure Berechnung erneut auszufuehren.

Warmup-Strategien loesen das Thundering-Herd-Problem indirekt, indem sie den Cache fuellen, bevor echter paralleler Traffic ueberhaupt entsteht. Ein systematischer Crawler, der Seiten nacheinander statt parallel abruft, erzeugt genau eine Datenbankabfrage pro Seite und vermeidet die Duplikation, die bei echten Nutzern in Kombination mit einem leeren Cache entstehen wuerde.

3. Warmup-Crawler: den Full-Page-Cache gezielt fuellen

Ein Warmup-Crawler ist ein Skript, das nach dem Deployment automatisch eine Liste wichtiger URLs aufruft und dabei den Redis-Full-Page-Cache fuellt, ohne dass echte Nutzer die erste, langsame Anfrage ausloesen muessen. Fuer Magento gibt es dafuer mehrere Ansaetze: das offizielle bin/magento cache:enable in Kombination mit einem externen HTTP-Crawler, spezialisierte Warmer-Module, oder ein einfaches Bash-Skript mit curl, das sequenziell oder mit begrenzter Parallelitaet durch eine Sitemap oder URL-Liste iteriert.

Wichtig ist, dass der Crawler echte Requests mit denselben Headern schickt wie ein Browser, insbesondere den Accept-Encoding-Header und einen realistischen User-Agent, weil Magentos Varnish- oder Full-Page-Cache-Layer unterschiedliche Cache-Eintraege fuer unterschiedliche Kontexte anlegen kann. Ein Crawler, der diese Header ignoriert, fuellt unter Umstaenden einen Cache-Eintrag, den echte Browser gar nicht nutzen, weil ihre Anfrage geringfuegig anders aussieht.


#!/usr/bin/env bash
# warmup.sh: sequential Redis cache warmup crawler for Magento
set -euo pipefail

BASE_URL="https://shop.example.com"
URL_LIST="/var/www/deploy/warmup-urls.txt"
CONCURRENCY=4
LOG_FILE="/var/log/magento/warmup-$(date +%Y%m%d-%H%M%S).log"

echo "[INFO] Starting cache warmup with concurrency=${CONCURRENCY}" | tee "$LOG_FILE"

# xargs runs requests with bounded parallelism, avoiding a new thundering herd
cat "$URL_LIST" | xargs -P "$CONCURRENCY" -I {} \
  curl -s -o /dev/null -w "%{http_code} %{time_total}s {}\n" \
    -H "Accept-Encoding: gzip, deflate" \
    -H "User-Agent: Mozilla/5.0 (compatible; MironsoftWarmupBot/1.0)" \
    "${BASE_URL}{}" >> "$LOG_FILE"

echo "[INFO] Warmup complete. Requests logged to ${LOG_FILE}"

4. Die richtigen URLs fuer den Warmup auswaehlen

Ein Warmup-Crawler, der versucht, den kompletten Katalog nach jedem Deployment durchzugehen, verschwendet Zeit und Ressourcen. Sinnvoller ist eine priorisierte URL-Liste, die auf tatsaechlichen Traffic-Daten basiert: die Startseite, die wichtigsten Kategorieseiten, die meistbesuchten Produktseiten und statische Seiten wie AGB oder Checkout-Einstiegsseiten. Diese Liste laesst sich automatisiert aus den Zugriffszahlen von Google Analytics oder aus den Access-Logs des Webservers der letzten 30 Tage ableiten.

Fuer sehr grosse Kataloge mit hunderttausenden Produkten ist es weder praktikabel noch noetig, jede einzelne Seite vorzuwaermen. Die Pareto-Regel greift hier zuverlaessig: meist erzeugen 20 Prozent der Seiten 80 Prozent des Traffics, und ein Warmup, der genau diese Top-URLs abdeckt, reduziert die Datenbank-Last nach dem Deployment bereits um den Grossteil, ohne den Crawler-Lauf unnoetig in die Laenge zu ziehen. Die restlichen, seltener aufgerufenen Seiten fuellen sich organisch durch echten Nutzer-Traffic, allerdings mit einer geringeren Wahrscheinlichkeit fuer gleichzeitige parallele Zugriffe und damit einem geringeren Thundering-Herd-Risiko.


# Generate a prioritized warmup URL list from the last 30 days of Nginx access logs
awk '{print $7}' /var/log/nginx/shop.example.com-access.log \
  | grep -E '^/(catalog|category|checkout|customer)?' \
  | sort | uniq -c | sort -rn \
  | head -n 500 \
  | awk '{print $2}' > /var/www/deploy/warmup-urls.txt

wc -l /var/www/deploy/warmup-urls.txt

5. Objektcache-Preload fuer Kategorien und Konfiguration

Neben dem Full-Page-Cache lohnt sich ein gezielter Preload des Magento-Objektcaches in Redis, insbesondere fuer Daten, die auf fast jeder Seite gebraucht werden: die Kategoriebaum-Struktur, die Store-Konfiguration, aktive Layered-Navigation-Attribute und Layout-XML-Merges. Diese Daten aendern sich selten, werden aber bei jedem Request gelesen, weshalb ein fehlender Eintrag hier besonders teuer ist, weil er von praktisch jedem Seitentyp gleichzeitig betroffen ist.

Ein einfaches PHP-Skript, das ueber die Magento-Bootstrap-Klasse laeuft, kann diese kritischen Objektcache-Eintraege gezielt vorab befuellen, indem es die entsprechenden Repository-Methoden einmal aufruft, noch bevor der Crawler startet. Das stellt sicher, dass selbst der allererste Full-Page-Cache-Warmup-Request bereits auf einen teilweise gefuellten Objektcache trifft und nicht zusaetzlich die Basisdaten neu laden muss.


<?php
// bin/warmup-object-cache.php: preload frequently used object cache entries
require __DIR__ . '/../app/bootstrap.php';

$bootstrap = \Magento\Framework\App\Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$state = $objectManager->get(\Magento\Framework\App\State::class);
$state->setAreaCode('frontend');

$storeManager = $objectManager->get(\Magento\Store\Model\StoreManagerInterface::class);
$categoryRepository = $objectManager->get(\Magento\Catalog\Api\CategoryRepositoryInterface::class);

foreach ($storeManager->getStores() as $store) {
    echo "[INFO] Warming category tree for store: {$store->getCode()}\n";
    // Touching the root category forces Magento to rebuild and cache the tree
    $categoryRepository->get((int) $store->getRootCategoryId(), $store->getId());
}

echo "[INFO] Object cache preload complete\n";

6. Warmup in die Deployment-Pipeline integrieren

Warmup sollte kein manueller Schritt sein, sondern fester Bestandteil der Deployment-Pipeline, unmittelbar nach dem Cache-Flush und vor der Freigabe des Traffics auf die neue Version. In der klassischen Reihenfolge steht Warmup direkt nach bin/magento cache:flush und vor dem Entfernen einer eventuell aktiven Maintenance-Page oder dem Umschalten des Load Balancers auf den neuen Deployment-Slot.

Ein haeufiger Fehler ist, den Warmup-Schritt zeitlich zu knapp zu bemessen oder ihn im Hintergrund laufen zu lassen, waehrend der Traffic bereits freigegeben wird. Das unterlaeuft den ganzen Zweck der Massnahme, weil echte Nutzer dann parallel zum Crawler auf denselben leeren Cache treffen. Sauberer ist es, den Maintenance-Modus erst nach erfolgreichem Abschluss des Warmup-Laufs zu deaktivieren, sodass zum Zeitpunkt der Freigabe bereits ein signifikanter Teil des Caches gefuellt ist.


#!/usr/bin/env bash
# deploy-with-warmup.sh: deployment sequence with cache warmup before traffic release
set -euo pipefail

echo "[STEP 1] Enabling maintenance mode"
bin/magento maintenance:enable

echo "[STEP 2] Running setup upgrade and flushing cache"
bin/magento setup:upgrade
bin/magento cache:flush

echo "[STEP 3] Preloading object cache"
php bin/warmup-object-cache.php

echo "[STEP 4] Running full-page-cache warmup crawler"
./warmup.sh

echo "[STEP 5] Verifying warmup coverage before releasing traffic"
HIT_RATIO=$(redis-cli -n 1 info stats | grep keyspace_hits | cut -d: -f2)
echo "[INFO] Current keyspace_hits: ${HIT_RATIO}"

echo "[STEP 6] Disabling maintenance mode, traffic is released"
bin/magento maintenance:disable

7. Blue-Green-Deployments und vorgewaermter Cache

Bei Blue-Green-Deployments laesst sich das Kaltstart-Problem noch eleganter loesen: die neue Version laeuft parallel zur alten auf einer separaten Infrastruktur, mit einem eigenen, zunaechst leeren Redis-Cache. Der Warmup-Crawler laeuft gegen diese neue Umgebung, waehrend die alte Version weiterhin den gesamten Produktivtraffic bedient. Erst wenn der Cache der neuen Umgebung ausreichend gefuellt ist, schaltet der Load Balancer den Traffic um.

Dieser Ansatz eliminiert das Thundering-Herd-Problem fast vollstaendig, weil zu keinem Zeitpunkt echter Nutzer-Traffic auf einen leeren Cache trifft. Die Kosten dafuer sind zusaetzliche Infrastruktur, die parallel betrieben werden muss, und ein etwas laengeres Deployment-Fenster, weil der Warmup vor dem Umschalten abgeschlossen sein muss. Fuer Shops mit hohem Umsatz pro Minute ist dieser Mehraufwand meist gerechtfertigt, weil ein einziger fehlgeschlagener Deployment-Traffic-Spike deutlich teurer sein kann.

8. Erfolg messen: Hit-Rate und Ladezeiten ueberwachen

Ob ein Warmup-Lauf tatsaechlich wirkt, laesst sich direkt an der Redis-Hit-Rate ablesen. Der Befehl INFO stats liefert keyspace_hits und keyspace_misses, aus denen sich die Trefferquote berechnen laesst. Direkt nach einem erfolgreichen Warmup sollte die Miss-Rate fuer die vorgewaermten URLs nahe null liegen, waehrend sie ohne Warmup in den ersten Minuten nach dem Deployment deutlich ueber 50 Prozent liegen kann.

Zusaetzlich zur reinen Hit-Rate lohnt sich die Beobachtung der Antwortzeiten in den ersten fuenf Minuten nach jedem Deployment, etwa ueber Application-Performance-Monitoring-Tools. Ein wirksamer Warmup zeigt sich darin, dass die p95-Antwortzeit direkt nach der Freigabe nahe am normalen Niveau bleibt, statt kurzzeitig anzusteigen. Diese Metrik eignet sich gut als automatisierter Check in der Pipeline, der ein Deployment als fehlgeschlagen markiert, wenn die Antwortzeiten nach dem Warmup nicht innerhalb eines definierten Schwellwerts liegen.


# Compute Redis hit ratio before and after a warmup run
before_hits=$(redis-cli -p 6381 info stats | grep -oP 'keyspace_hits:\K\d+')
before_miss=$(redis-cli -p 6381 info stats | grep -oP 'keyspace_misses:\K\d+')

./warmup.sh

after_hits=$(redis-cli -p 6381 info stats | grep -oP 'keyspace_hits:\K\d+')
after_miss=$(redis-cli -p 6381 info stats | grep -oP 'keyspace_misses:\K\d+')

echo "Hits before: ${before_hits}, misses before: ${before_miss}"
echo "Hits after:  ${after_hits}, misses after:  ${after_miss}"

# Fail the pipeline if miss rate stays too high after warmup
delta_miss=$(( after_miss - before_miss ))
if (( delta_miss > 500 )); then
  echo "[ERROR] Warmup coverage insufficient: ${delta_miss} new misses" >&2
  exit 1
fi

9. Warmup-Strategien im Vergleich

Je nach Shop-Groesse, Traffic-Muster und Infrastruktur eignen sich unterschiedliche Warmup-Ansaetze. Die folgende Tabelle vergleicht die gaengigsten Strategien fuer Magento-Shops mit Redis als Cache-Backend.

Strategie Aufwand Thundering-Herd-Schutz Geeignet fuer
Kein Warmup Keiner Kein Schutz Nur Traffic-arme Testumgebungen
Einfacher Sequential-Crawler Gering Gut Kleine bis mittlere Shops
Priorisierter Top-URL-Crawler Mittel Sehr gut Grosse Kataloge, hoher Traffic
Objektcache-Preload-Skript Mittel Ergaenzend Shops mit vielen Kategorien/Attributen
Blue-Green mit Vorab-Warmup Hoch Exzellent Umsatzstarke Shops, hohe SLAs

Die meisten Magento-Shops kommen mit einem priorisierten Top-URL-Crawler in Kombination mit einem Objektcache-Preload-Skript bereits sehr weit. Blue-Green-Deployments mit vollstaendigem Vorab-Warmup lohnen sich vor allem dann, wenn jede Minute mit erhoehten Ladezeiten direkt messbaren Umsatzverlust bedeutet.

10. Zusammenfassung

Ein kalter Redis-Cache nach dem Deployment ist kein Randproblem, sondern eine der haeufigsten Ursachen fuer Datenbank-Lastspitzen und Performance-Einbrueche direkt nach einem Release. Warmup-Crawler, die priorisierte URL-Listen sequenziell oder mit begrenzter Parallelitaet abrufen, fuellen den Full-Page-Cache proaktiv, bevor echter Nutzer-Traffic auf die neue Version trifft. Ergaenzend sorgt ein gezieltes Objektcache-Preload-Skript dafuer, dass Basisdaten wie Kategoriebaum und Store-Konfiguration bereits vor dem ersten Request verfuegbar sind.

Die entscheidende Regel lautet: Warmup gehoert vor die Traffic-Freigabe, nicht danach. Ob per klassischem Maintenance-Mode-Fenster oder per Blue-Green-Deployment mit separater Warmup-Umgebung, in beiden Faellen soll kein echter Nutzer jemals auf einen leeren Redis-Cache treffen. Monitoring von Hit-Rate und Antwortzeiten in den ersten Minuten nach jedem Deployment macht sichtbar, ob die Warmup-Strategie tatsaechlich wirkt.

Cache-Warmup-Strategien fuer Magento: Das Wichtigste auf einen Blick

Das Problem

Kalter Redis-Cache nach Deployment trifft echten Traffic gleichzeitig, was zu Datenbank-Lastspitzen fuehrt.

Warmup-Crawler

Priorisierte Top-URL-Liste sequenziell oder begrenzt parallel abrufen, bevor Traffic freigegeben wird.

Objektcache-Preload

Kategoriebaum und Store-Konfiguration gezielt vorab befuellen, bevor der Full-Page-Cache-Warmup laeuft.

Pipeline-Integration

Warmup zwischen Cache-Flush und Traffic-Freigabe, idealerweise mit Blue-Green-Deployment.

11. FAQ: Cache-Warmup-Strategien fuer Magento

1Warum ist der Cache nach Deployment leer?
cache:flush im Deployment leert Full-Page-Cache und Objektcache in Redis, um veraltete Daten zu entfernen.
2Was ist Thundering Herd?
Viele parallele Requests starten dieselbe teure Berechnung gleichzeitig, statt sie einmal zu teilen. Erzeugt Lastspitzen.
3Wie waehle ich Warmup-URLs?
Aus Access-Logs oder Analytics die meistbesuchten URLs extrahieren. 20 Prozent der Seiten erzeugen oft 80 Prozent des Traffics.
4Parallel oder sequenziell crawlen?
Begrenzt parallel mit wenigen gleichzeitigen Requests ist meist optimal, um Dauer und Last auszubalancieren.
5Was ist Objektcache-Preload?
Vorab-Befuellung von Basisdaten wie Kategoriebaum, die von praktisch jeder Seite gebraucht werden.
6Wo im Prozess gehoert Warmup hin?
Zwischen Cache-Flush und Traffic-Freigabe, waehrend Maintenance-Mode aktiv ist oder auf separater Umgebung.
7Was bringt Blue-Green fuer Warmup?
Warmup laeuft gegen neue Umgebung, waehrend alte weiterhin Traffic bedient. Kein Nutzer trifft je auf leeren Cache.
8Wie messe ich Warmup-Erfolg?
Redis keyspace_hits/misses und p95-Antwortzeit in den ersten Minuten nach Traffic-Freigabe beobachten.
9Muss der ganze Katalog vorgewaermt werden?
Nein, eine priorisierte Top-URL-Liste reicht bei grossen Katalogen meist vollstaendig aus.
10Welche Header sollte der Crawler setzen?
Accept-Encoding und realistischer User-Agent, damit derselbe Cache-Eintrag wie bei echten Browsern entsteht.