Multi-Datenbank-Trennung: Cache, Session und FPC sauber isolieren
AI generated
SET
TTL
Redis · Magento · Performance · Caching
Multi-Datenbank-Trennung: Cache, Session und FPC sauber isolieren
database-Indizes, Praefixe und Eviction-Policy richtig kombinieren

Eine gemeinsame Redis-Instanz fuer Cache, Session und Full-Page-Cache ohne saubere Datenbank-Trennung ist eine der unterschaetztesten operativen Risikoquellen in Magento-Betriebssettings. Dieser Artikel erklaert, warum eigene database-Indizes pro Rolle Key-Kollisionen verhindern, wann getrennte Redis-Instanzen sinnvoll sind und wie sich die Eviction-Policy je nach Rolle unterschiedlich konfigurieren laesst.

14 Min. Lesezeit database-Index · Eviction-Policy · Key-Praefixe Redis 7.x · Magento 2.4.8 · PHP 8.4

1. Warum eine gemeinsame Redis-Instanz fuer alles problematisch ist

Es ist technisch moeglich, Cache, Session und Full-Page-Cache in Magento auf denselben Redis-Datenbank-Index zu legen. Der Shop startet damit, die Seiten laden, und auf den ersten Blick scheint alles zu funktionieren. Das Problem zeigt sich erst unter Last oder bei operativen Eingriffen: Ohne Datenbank-Trennung teilen sich alle drei Rollen denselben Schluesselraum, was mehrere subtile, aber gefaehrliche Risiken erzeugt.

Das offensichtlichste Risiko ist ein versehentliches FLUSHDB, das eigentlich nur den Konfigurations-Cache leeren sollte, aber gleichzeitig alle aktiven Kundensessions loescht, weil sie im selben Index liegen. Ein weniger offensichtliches Risiko ist die gemeinsame Eviction: Erreicht Redis sein maxmemory-Limit, entscheidet die konfigurierte Policy, welche Schluessel entfernt werden, ohne Ruecksicht darauf, ob es sich um einen unwichtigen Cache-Eintrag oder eine aktive Session handelt. Ohne Datenbank-Trennung ist diese Unterscheidung unmoeglich.

Der dritte Aspekt betrifft Monitoring und Kapazitaetsplanung: Ohne getrennte Datenbanken laesst sich nicht mehr feststellen, wie viel Speicher tatsaechlich vom Cache, wie viel von Sessions und wie viel vom Full-Page-Cache belegt wird. Diese Sichtbarkeit ist aber Voraussetzung fuer fundierte Entscheidungen bei Speicherplanung und Skalierung, die dieser Artikel im weiteren Verlauf behandelt.

2. Redis-Datenbank-Indizes: das SELECT-Konzept

Redis unterstuetzt standardmaessig 16 logische Datenbanken innerhalb einer einzelnen Instanz, nummeriert von 0 bis 15, konfigurierbar ueber databases in redis.conf. Jede logische Datenbank ist ein vollstaendig getrennter Schluesselraum, erreichbar ueber den SELECT-Befehl oder, bei redis-cli, ueber die Option -n. Wichtig zu verstehen: Diese Datenbank-Trennung ist rein logisch, alle Datenbanken teilen sich denselben Arbeitsspeicher, denselben Prozess und dieselbe maxmemory-Grenze der Instanz.

Das bedeutet: Die Trennung ueber Datenbank-Indizes loest das Kollisionsproblem vollstaendig, aber nicht das Ressourcen-Isolationsproblem. Wenn der Cache unter Last waechst und die globale maxmemory-Grenze erreicht, kann das theoretisch auch Sessiondaten in einer anderen Datenbank betreffen, je nach konfigurierter maxmemory-policy. Diese Unterscheidung zwischen logischer Datenbank-Trennung und physischer Ressourcen-Trennung ist zentral fuer die Entscheidung, ob eine oder mehrere Redis-Instanzen benoetigt werden, was in Abschnitt 6 vertieft wird.

3. env.php: separate database-Werte fuer Cache, Session und FPC

Die praktische Umsetzung der Datenbank-Trennung in Magento erfolgt ueber drei unabhaengige database-Parameter in app/etc/env.php: einen fuer den regulaeren Cache unter cache.frontend.default.backend_options.database, einen fuer den Full-Page-Cache unter cache.frontend.page_cache.backend_options.database, und einen fuer Sessions unter session.redis.database. Die uebliche Konvention ist, Index 0 fuer den allgemeinen Cache, Index 1 fuer den Full-Page-Cache und Index 2 fuer Sessions zu verwenden.

Diese Konfiguration kostet keine zusaetzliche Latenz, weil alle Indizes innerhalb derselben TCP-Verbindung und desselben Redis-Prozesses erreichbar sind. Der Aufwand fuer die Datenbank-Trennung beschraenkt sich also auf drei zusaetzliche Zeilen in env.php, bringt aber erhebliche operative Sicherheit gegenueber der Ein-Datenbank-Variante.


<?php
// app/etc/env.php - explicit database separation for cache, page cache and session
return [
    'cache' => [
        'frontend' => [
            'default' => [
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => '127.0.0.1',
                    'port' => '6379',
                    'database' => '0', // General config/layout/block_html cache
                ],
            ],
            'page_cache' => [
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => '127.0.0.1',
                    'port' => '6379',
                    'database' => '1', // Full page cache, separated from general cache
                ],
            ],
        ],
    ],
    'session' => [
        'save' => 'redis',
        'redis' => [
            'host' => '127.0.0.1',
            'port' => '6379',
            'database' => '2', // Sessions, isolated from both cache roles
        ],
    ],
];

4. Key-Kollisionen vermeiden: Praefixe und Namensraeume

Selbst mit sauberer Datenbank-Trennung auf Index-Ebene lohnt sich ein zusaetzlicher Blick auf Key-Praefixe, besonders wenn mehrere Magento-Installationen dieselbe Redis-Instanz nutzen, etwa in Multi-Tenant- oder Staging-Umgebungen. Magento selbst nutzt bereits interne Praefixe wie zc:k: fuer Cache-Eintraege, doch bei mehreren unabhaengigen Magento-Installationen auf demselben Datenbank-Index kollidieren diese Praefixe trotzdem, weil beide Installationen dieselben Cache-Keys fuer aehnliche Entitaeten generieren koennen.

Die robuste Loesung ist entweder eine vollstaendige Datenbank-Trennung pro Installation, also eigene Indizes 3, 4, 5 und so weiter fuer eine zweite Installation, oder komplett getrennte Redis-Instanzen bei sehr vielen Mandanten. Ein zusaetzlicher id_prefix-Parameter in den backend_options kann als weitere Absicherung dienen, ersetzt aber nicht die grundsaetzliche Trennung nach Rolle und Mandant.


<?php
// app/etc/env.php - additional id_prefix safeguard for a second tenant
// sharing the same Redis instance and database index range
'cache' => [
    'frontend' => [
        'default' => [
            'backend' => 'Cm_Cache_Backend_Redis',
            'backend_options' => [
                'server' => '127.0.0.1',
                'port' => '6379',
                'database' => '3', // Dedicated index for the second Magento installation
                'id_prefix' => 'tenant2_', // Extra namespace safeguard
            ],
        ],
    ],
],

5. Eviction-Policy pro Rolle erklaert

Redis entfernt bei Erreichen der maxmemory-Grenze automatisch Schluessel gemaess der konfigurierten maxmemory-policy. Fuer Cache-Daten ist allkeys-lru meist die richtige Wahl: Redis entfernt die am laengsten nicht genutzten Schluessel, unabhaengig davon, ob eine explizite TTL gesetzt ist, was fuer Cache-Daten unproblematisch ist, weil sie jederzeit neu berechnet werden koennen.

Fuer Sessiondaten ist diese Policy riskanter: Wird eine aktive Session per LRU entfernt, obwohl sie gerade genutzt wird, verliert der Kunde seinen Warenkorb mitten im Checkout. Deshalb ist es empfehlenswert, Sessiondaten in einer Instanz oder Konfiguration mit ausreichend grosszuegiger maxmemory-Grenze zu betreiben, sodass Eviction dort im Normalbetrieb praktisch nie greift, kombiniert mit volatile-lru, das nur Schluessel mit gesetzter TTL entfernt und damit versehentliches Loeschen persistenter Daten verhindert.

Diese unterschiedlichen Anforderungen sind ein starkes Argument fuer physisch getrennte Redis-Instanzen bei groesseren Installationen: Nur so lassen sich unterschiedliche maxmemory-policy-Werte pro Rolle tatsaechlich unabhaengig konfigurieren, weil maxmemory-policy eine instanzweite Einstellung ist und nicht pro Datenbank-Index gesetzt werden kann.

In der Praxis lohnt es sich, den Wert evicted_keys aus redis-cli INFO stats regelmaessig pro Instanz zu beobachten. Steigt dieser Wert bei einer gemeinsam genutzten Instanz an, laesst sich ohne Datenbank-Trennung nicht mehr feststellen, ob Cache- oder Session-Schluessel betroffen waren, was die Fehlersuche unnoetig erschwert.


# Check current eviction policy of the running Redis instance
redis-cli CONFIG GET maxmemory-policy

# Recommended policy for a cache-only instance
redis-cli CONFIG SET maxmemory-policy allkeys-lru

# Recommended policy for a session-only instance (never evict without TTL)
redis-cli CONFIG SET maxmemory-policy volatile-lru

# Check memory usage broken down per logical database
redis-cli INFO keyspace

# Verify maxmemory-policy is a global instance setting, not per database
redis-cli CONFIG GET maxmemory

# Count evicted keys since last restart, per instance
redis-cli INFO stats | grep evicted_keys

6. Wann getrennte Redis-Instanzen statt nur Datenbank-Indizes sinnvoll sind

Fuer kleine bis mittlere Magento-Shops reicht logische Datenbank-Trennung ueber Indizes meist vollstaendig aus. Ab einem gewissen Traffic-Volumen oder bei besonders speicherintensiven Katalogen lohnt sich jedoch der Schritt zu physisch getrennten Redis-Instanzen, typischerweise auf unterschiedlichen Ports oder sogar unterschiedlichen Hosts. Der Hauptgrund ist Ressourcen-Isolation: Ein Cache-Spike, der durch eine grosse Kategorieaenderung ausgeloest wird, kann dann nicht mehr die maxmemory-Grenze der Session-Instanz beeinflussen.

Ein weiterer Grund fuer getrennte Instanzen ist unterschiedliches Skalierungsverhalten: Sessiondaten wachsen naeherungsweise proportional zum gleichzeitigen Traffic, waehrend Cache-Daten eher proportional zur Katalog-Groesse wachsen. Getrennte Instanzen erlauben es, jede Rolle unabhaengig zu skalieren, etwa den Session-Server bei einem Traffic-Anstieg grosszuegiger zu dimensionieren, ohne den Cache-Server anzufassen.

7. Persistenz-Strategien je Rolle: RDB und AOF

Cache-Daten muessen einen Redis-Neustart nicht ueberleben, da sie jederzeit aus der Datenbank oder durch erneutes Rendering rekonstruiert werden koennen. Fuer eine reine Cache-Instanz kann Persistenz daher komplett deaktiviert werden (save "" in redis.conf), was Schreiblast reduziert und die Instanz schneller macht.

Sessiondaten hingegen sollten idealerweise einen Neustart ueberstehen, sonst werden bei jedem Redis-Neustart alle eingeloggten Kunden ausgeloggt und alle Warenkoerbe geleert. Fuer die Session-Instanz ist daher AOF (appendonly yes) mit appendfsync everysec die sinnvolle Wahl, ein guter Kompromiss zwischen Datensicherheit und Schreibperformance. Diese unterschiedlichen Persistenz-Anforderungen sind ein weiteres starkes Argument fuer die Datenbank-Trennung auf Instanz-Ebene, weil Persistenzeinstellungen ebenfalls instanzweit gelten.


# redis.conf snippet for a pure cache instance - persistence disabled
save ""
appendonly no

# redis.conf snippet for a session instance - durable but fast
appendonly yes
appendfsync everysec

8. redis-cli: Datenbanken wechseln und pruefen

Zur praktischen Verifikation der Datenbank-Trennung wechselt SELECT innerhalb einer redis-cli-Sitzung zwischen Indizes, waehrend die Kommandozeilenoption -n direkt beim Start eine Datenbank auswaehlt. redis-cli -n 0 DBSIZE, redis-cli -n 1 DBSIZE und redis-cli -n 2 DBSIZE liefern in Sekunden einen Ueberblick, wie sich die Schluesselzahl auf Cache, Full-Page-Cache und Sessions verteilt, und decken sofort auf, wenn eine Rolle faelschlich denselben Index wie eine andere verwendet.


# Compare key counts across the three role-specific databases
redis-cli -n 0 DBSIZE
redis-cli -n 1 DBSIZE
redis-cli -n 2 DBSIZE

# Switch database inside an interactive redis-cli session
redis-cli
> SELECT 2
> DBSIZE

redis-cli INFO keyspace zeigt in einem einzigen Befehl alle aktiven Datenbanken mit ihrer jeweiligen Schluesselzahl und der Anzahl Schluessel mit gesetztem Ablaufdatum. Fehlt eine erwartete Datenbank in dieser Ausgabe komplett, deutet das darauf hin, dass die entsprechende env.php-Konfiguration nicht wie beabsichtigt greift.

9. Ein Index vs getrennte Indizes vs getrennte Instanzen

Die folgende Tabelle fasst die drei gaengigen Architekturvarianten zusammen und ordnet sie nach Sicherheit und Aufwand.

Architektur Key-Kollisionen Ressourcen-Isolation Betriebsaufwand
Ein gemeinsamer Index Hoch, sehr riskant Keine Minimal, aber nicht empfohlen
Getrennte Datenbank-Indizes Keine Nur logisch, geteilter RAM Gering, drei Zeilen in env.php
Getrennte Redis-Instanzen Keine Vollstaendig, unabhaengige maxmemory Hoeher, mehrere Prozesse verwalten
Getrennte Instanzen mit Replikation Keine Vollstaendig plus Ausfallsicherheit Am hoechsten, Replikation und Failover pflegen

Fuer die meisten Magento-Shops sind getrennte Datenbank-Indizes der richtige Ausgangspunkt, weil sie das Kollisionsrisiko vollstaendig eliminieren und minimalen Zusatzaufwand erfordern. Erst bei nachweisbarem Ressourcendruck oder unterschiedlichen Eviction- und Persistenzanforderungen lohnt sich der Schritt zu getrennten Instanzen, verbunden mit dem zusaetzlichen Betriebsaufwand mehrerer Redis-Prozesse.

10. Zusammenfassung

Saubere Datenbank-Trennung zwischen Cache, Session und Full-Page-Cache ist keine kosmetische Konfigurationsdetail, sondern eine grundlegende Absicherung gegen Key-Kollisionen und riskante Eviction-Effekte. Drei separate database-Werte in env.php reichen fuer die meisten Installationen aus, um das groesste Risiko, versehentliche Datenverluste durch geteilte Schluesselraeume, vollstaendig zu eliminieren.

Fuer groessere Installationen mit unterschiedlichen Anforderungen an Eviction-Policy und Persistenz zwischen Cache und Session ist der zusaetzliche Schritt zu physisch getrennten Redis-Instanzen sinnvoll. Die Datenbank-Trennung auf Indexebene bleibt dabei die Grundvoraussetzung, unabhaengig davon, ob am Ende eine oder mehrere Redis-Instanzen zum Einsatz kommen.

Redis Datenbank-Trennung fuer Magento - Das Wichtigste auf einen Blick

Drei getrennte Indizes

Cache, Full-Page-Cache und Session jeweils eigene database-Werte in env.php zuweisen.

Eviction-Policy pruefen

allkeys-lru fuer Cache, volatile-lru fuer Session, idealerweise pro Instanz getrennt konfiguriert.

Persistenz unterscheiden

Cache ohne Persistenz, Session mit AOF, um Ausloggen bei jedem Neustart zu vermeiden.

Getrennte Instanzen ab Skalierungsdruck

Nur physisch getrennte Instanzen erlauben unabhaengige maxmemory-Grenzen und Policies.

11. FAQ: Multi-Datenbank-Trennung in Redis fuer Magento

1Ein gemeinsamer Index reicht nicht?
Cache und Session teilen sich den Schluesselraum. FLUSHDB oder Eviction koennen dann versehentlich aktive Sessions treffen.
2Wie viele Datenbanken bietet Redis?
16 Datenbanken (0-15), konfigurierbar ueber databases in redis.conf, alle teilen sich denselben Arbeitsspeicher.
3Kostet mehrere Indizes Latenz?
Nein, alle Indizes laufen ueber dieselbe Verbindung und denselben Prozess, kein messbarer Overhead.
4Passende Policy fuer Cache-Daten?
allkeys-lru, weil Cache-Daten jederzeit neu berechnet werden koennen.
5Passende Policy fuer Session-Daten?
volatile-lru mit grosszuegiger maxmemory-Grenze, damit Eviction im Normalbetrieb praktisch nie greift.
6Wann getrennte Instanzen?
Bei unterschiedlichen Eviction- oder Persistenzanforderungen, da diese Einstellungen instanzweit gelten.
7Persistenz fuer Cache-Instanz aktivieren?
In der Regel nicht, Cache laesst sich problemlos neu aufbauen. save "" deaktiviert Persistenz.
8Warum Persistenz fuer Session?
Ohne Persistenz werden Kunden bei jedem Neustart ausgeloggt. AOF mit everysec ist ein guter Kompromiss.
9Trennung pruefen?
redis-cli -n X DBSIZE pro Index oder redis-cli INFO keyspace fuer den Gesamtueberblick.
10Mehrere Installationen auf einer Instanz?
Nur mit eigenen Index-Bloecken pro Installation, zusaetzlich id_prefix als weitere Absicherung.