RedisJSON: Strukturierte Dokumente nativ in Redis speichern
AI generated
SET
TTL
Redis Stack / RedisJSON
RedisJSON: Strukturierte Dokumente nativ speichern
JSONPath-Zugriff statt kompletter Serialisierung

Wer JSON-Daten bisher als String in Redis abgelegt hat, kennt das Problem: Jede noch so kleine Änderung an einem einzelnen Feld erfordert, das komplette Dokument zu laden, zu deserialisieren, zu ändern und wieder als Ganzes zurückzuschreiben. RedisJSON löst dieses Problem, indem es JSON-Dokumente als eigenen, nativen Datentyp verwaltet und über JSONPath-Ausdrücke gezielten Zugriff auf einzelne Pfade erlaubt, ohne das gesamte Dokument zu bewegen.

12 Min. Lesezeit RedisJSON JSONPath Redis Stack JSON.SET Teil-Updates

1. Das Problem mit String-basiertem JSON in Redis

Ohne RedisJSON gibt es in Redis nur eine Möglichkeit, ein JSON-Dokument zu speichern: als serialisierter String über SET und GET. Für Redis selbst ist der Inhalt dabei bedeutungslos, es handelt sich schlicht um eine Byte-Folge. Jede Anwendung, die auch nur ein einzelnes Feld eines Dokuments lesen oder ändern möchte, muss den kompletten String übertragen, im Client deserialisieren, die gewünschte Änderung vornehmen und das gesamte Dokument wieder serialisiert zurückschreiben.

Bei kleinen Dokumenten fällt dieser Umweg kaum ins Gewicht, bei größeren, verschachtelten Strukturen, etwa Produktkonfigurationen mit mehreren hundert Attributen und Varianten, summiert sich der Aufwand jedoch spürbar. Zusätzlich entsteht ein Race-Condition-Risiko: Zwei parallele Prozesse, die dasselbe Dokument lesen, ändern und zurückschreiben, überschreiben sich gegenseitig, wenn nicht zusätzlich mit WATCH, MULTI und EXEC oder Lua-Skripten gegen konkurrierende Schreibzugriffe abgesichert wird.

2. RedisJSON als eigener Datentyp im Redis Stack

RedisJSON ist ein Modul, das seit Redis Stack fest zum Standardpaket gehört und in Redis Enterprise sowie bei den meisten Managed-Redis-Anbietern verfügbar ist. Es führt einen neuen Datentyp ein, der JSON-Dokumente intern als Baum aus Werten abbildet, ähnlich wie es Dokumentendatenbanken tun, nur innerhalb der bekannten Redis-Infrastruktur mit ihrer gewohnten Latenz und ihrem Persistenzmodell.

Der zentrale Unterschied zu String-basiertem JSON zeigt sich schon beim Anlegen: JSON.SET erwartet neben dem Key auch einen JSONPath, an dem das Dokument oder ein Teilbereich davon geschrieben wird. Das gesamte Dokument mit dem Pfad $ zu adressieren funktioniert weiterhin wie ein klassisches SET, doch ab hier öffnet sich die eigentliche Stärke des Moduls: gezielter Zugriff auf einzelne Knoten des Baums.


redis-cli JSON.SET produkt:4711 $ '{"sku":"SHIRT-BLAU-M","name":"Basic Shirt Blau","preis":29.90,"lager":{"gesamt":140,"reserviert":12},"varianten":["S","M","L","XL"]}'

redis-cli JSON.GET produkt:4711 $.preis
# [29.9]

redis-cli JSON.TYPE produkt:4711 $.varianten
# ["array"]

3. JSONPath: Gezielter Lesezugriff ohne das gesamte Dokument zu laden

JSONPath-Ausdrücke erlauben es, exakt den Teil eines Dokuments anzufragen, der gebraucht wird. Statt produkt:4711 komplett zu laden, um nur den reservierten Lagerbestand zu prüfen, genügt JSON.GET produkt:4711 $.lager.reserviert. Bei Dokumenten mit vielen Kilobyte an Nutzdaten, etwa ausführlichen Produktbeschreibungen mit mehrsprachigen Attributen, reduziert das die übertragene Datenmenge drastisch und senkt entsprechend die Netzwerklatenz zwischen Anwendung und Redis-Instanz.

RedisJSON unterstützt sowohl die eingeschränkte, legacy-kompatible Pfadsyntax als auch das vollständige JSONPath mit Wildcards, Filtern und rekursiver Suche über die $-Notation. Damit lassen sich auch Abfragen wie alle Varianten mit einem Lagerbestand unter einem Schwellenwert formulieren, ohne die Filterlogik in die Anwendung auslagern zu müssen, was insbesondere bei stark lesenden Workloads die Client-Seite deutlich entlastet.


redis-cli JSON.GET produkt:4711 '$.varianten[?(@.lager<5)]'

redis-cli JSON.GET produkt:4711 $.lager.reserviert
# [12]

4. Atomare Teil-Updates statt Read-Modify-Write

Der praktische Kernvorteil von RedisJSON liegt bei Schreibzugriffen. Befehle wie JSON.SET mit einem spezifischen Pfad, JSON.NUMINCRBY für numerische Felder oder JSON.ARRAPPEND für Arrays ändern gezielt einen Teilbereich des Dokuments, atomar und ohne dass die Anwendung das gesamte Dokument vorher laden muss. Ein Lagerbestand lässt sich damit direkt im Redis-Server dekrementieren, ganz ohne Read-Modify-Write-Zyklus im Anwendungscode.

Das eliminiert die vorhin beschriebene Race Condition strukturell, weil Redis selbst für die Atomarität der Pfad-Operation sorgt. Zwei parallele Bestellprozesse, die gleichzeitig JSON.NUMINCRBY produkt:4711 $.lager.reserviert 1 ausführen, konkurrieren nicht miteinander. Jeder Aufruf wird serialisiert im Single-Threaded-Command-Loop von Redis verarbeitet, das Ergebnis ist immer konsistent, ganz ohne zusätzliches Locking im Anwendungscode.


redis-cli JSON.NUMINCRBY produkt:4711 $.lager.reserviert 1

redis-cli JSON.ARRAPPEND produkt:4711 $.varianten '"XXL"'

redis-cli JSON.GET produkt:4711 $.lager
# [{"gesamt":140,"reserviert":13}]

5. Performance im Vergleich zu String-basiertem JSON

Der Geschwindigkeitsgewinn von RedisJSON entsteht nicht dadurch, dass das Modul grundsätzlich schneller serialisiert als eine Anwendung, sondern dadurch, dass bei Teilzugriffen die komplette Serialisierung und Deserialisierung schlicht entfällt. Bei einem zehn Kilobyte großen Dokument, von dem nur ein einzelnes Preisfeld gelesen wird, überträgt String-basiertes JSON immer die vollen zehn Kilobyte über das Netzwerk und muss sie clientseitig parsen, RedisJSON überträgt nur die wenigen Bytes des angefragten Pfads.

Bei Schreibzugriffen verstärkt sich der Effekt weiter: Ein String-Update erfordert immer das komplette Dokument als neuen Wert, RedisJSON aktualisiert intern nur den betroffenen Teilbaum. Bei sehr großen Dokumenten mit vielen Kilobyte und häufigen kleinen Änderungen, etwa laufend aktualisierten Lagerbeständen in Produktkatalogen mit tausenden Artikeln, macht sich dieser Unterschied in Benchmarks deutlich in Latenz und Netzwerk-Durchsatz bemerkbar.

6. Praxisbeispiel: Produktkonfigurationsdaten strukturiert speichern

Ein typischer Anwendungsfall im E-Commerce-Kontext sind Produktkonfigurationen mit verschachtelten Attributen: Basisdaten, Preisstufen je Kundengruppe, Varianten mit eigenem Lagerbestand und Metadaten für unterschiedliche Verkaufskanäle. Statt diese Struktur in mehrere flache Redis-Keys aufzuteilen oder als einzelnen JSON-String zu cachen, bildet RedisJSON die gesamte Struktur in einem Dokument ab, das sich gezielt pro Pfad lesen und schreiben lässt.

In der Praxis bedeutet das: Ein Konfigurator-Frontend fragt beim Laden nur die für die Anzeige relevanten Pfade ab, etwa Preise und Verfügbarkeit je Variante, während ein Hintergrundjob, der Lagerbestände synchronisiert, ausschließlich die betroffenen Zahlenfelder mit JSON.NUMINCRBY aktualisiert. Beide Zugriffsarten laufen unabhängig voneinander, ohne sich gegenseitig durch volle Dokument-Overwrites zu blockieren oder zu überschreiben.


{
  "sku": "JACKE-SOMMER-42",
  "name": "Sommerjacke Leicht",
  "preisstufen": {
    "standard": 89.90,
    "haendler": 62.00,
    "vip": 74.90
  },
  "varianten": [
    {"größe": "M", "farbe": "blau", "lager": 34},
    {"größe": "L", "farbe": "blau", "lager": 12}
  ],
  "kanaele": ["web", "marketplace", "b2b-portal"]
}

7. Kombination mit RediSearch: Indizierte Abfragen über JSON-Dokumente

RedisJSON entfaltet seine volle Stärke oft erst in Kombination mit dem RediSearch-Modul, das Sekundärindizes direkt auf JSON-Dokumenten anlegen kann. Während RedisJSON den effizienten Zugriff per Key und Pfad ermöglicht, erlaubt RediSearch Abfragen über Attribute hinweg, etwa alle Produkte einer Kategorie mit einem Lagerbestand über einem Schwellenwert, ohne dass die Anwendung selbst über alle Keys iterieren muss.

Diese Kombination ersetzt in vielen Fällen keinen dedizierten Suchindex, reduziert aber den Bedarf an zusätzlicher Infrastruktur für einfache, attributbasierte Filterabfragen erheblich. Wer bereits RedisJSON für die Datenhaltung nutzt und nur gelegentlich über wenige Felder filtern muss, spart sich damit unter Umständen eine separate Elasticsearch- oder OpenSearch-Instanz für diesen Teilbereich der Anwendung.

8. Persistenz und Speicherverbrauch von JSON-Dokumenten

RedisJSON-Dokumente werden wie jeder andere Redis-Datentyp über die konfigurierte Persistenzstrategie gesichert, also über RDB-Snapshots, AOF oder eine Kombination aus beidem. Für den Server ist ein JSON-Dokument dabei kein Sonderfall, es wird beim Snapshot ebenso serialisiert wie eine Hash- oder Sorted-Set-Struktur, sodass sich an bestehenden Backup- und Replikationsprozessen nichts ändert.

Beim Speicherverbrauch lohnt sich ein genauer Blick: Die interne Baumstruktur von RedisJSON benötigt pro Knoten zusätzlichen Verwaltungs-Overhead gegenüber einem rohen, komprimierten JSON-String. Bei sehr vielen kleinen, tief verschachtelten Dokumenten kann der Speicherbedarf spürbar über dem eines vergleichbaren String-basierten Ansatzes liegen, was bei der Kapazitätsplanung für große Produktkataloge explizit berücksichtigt werden sollte, etwa über MEMORY USAGE-Stichproben auf repräsentativen Keys.


redis-cli MEMORY USAGE produkt:4711 SAMPLES 0

9. Client-Integration in PHP- und Magento-Umgebungen

Für die Anbindung an PHP-Anwendungen bieten sowohl phpredis, sofern mit RedisJSON-Unterstützung kompiliert, als auch Predis über generische Command-Aufrufe Zugriff auf die JSON.*-Befehle. In Magento-Kontexten lohnt sich RedisJSON vor allem für eigene, außerhalb des Standard-Cache-Frameworks liegende Datenstrukturen, etwa individuell aufgebaute Konfigurations- oder Feature-Flag-Speicher, weniger für den ohnehin durch das Framework abstrahierten Full-Page-Cache oder Session-Storage.

Ein häufiger Stolperstein in der Praxis: RedisJSON ist kein Bestandteil des Standard-Redis-Servers, sondern muss als Modul explizit geladen werden, entweder über Redis Stack oder eine manuell kompilierte .so-Datei. Wer RedisJSON in einer Produktionsumgebung einsetzen will, sollte vorab prüfen, ob der genutzte Managed-Service oder das Docker-Image das Modul tatsächlich mitbringt, denn ein fehlendes Modul führt bei JSON.SET nicht zu einem hilfreichen Fehler, sondern schlicht zu einem unbekannten Befehl.


redis-cli MODULE LIST
# 1) "name" "ReJSON" "ver" 20602
Aspekt String-basiertes JSON RedisJSON
Teilfeld lesen Komplettes Dokument laden und clientseitig parsen Direkter Zugriff per JSONPath ohne volle Deserialisierung
Teilfeld schreiben Read-Modify-Write-Zyklus im Anwendungscode nötig Atomares JSON.SET oder JSON.NUMINCRBY auf den Pfad
Race Conditions bei parallelen Writes Nur mit WATCH, MULTI und EXEC oder Lua vermeidbar Strukturell ausgeschlossen durch Pfad-Atomarität
Netzwerklast bei großen Dokumenten Immer die volle Dokumentgröße Nur die Größe des angefragten Pfads
Verfügbarkeit In jedem Redis-Server ohne Zusatzmodul Erfordert Redis Stack oder RedisJSON-Modul
Kombinierbarkeit mit Indizierung Nur über externe Indizes möglich Direkte Indizierung über RediSearch auf demselben Dokument

Mironsoft

Cache-Layer-Setup und Magento-Redis-Integration

Magento-Cache, der nicht richtig greift oder falsch konfiguriert ist?

Wir richten Redis als Cache- und Session-Backend für Magento sauber ein, tunen Speicherverbrauch und Eviction-Strategien und sorgen dafür, dass Full Page Cache und Session-Storage zuverlässig zusammenspielen.

Redis-Setup

Cache-, Session- und FPC-Backend produktionsreif für Magento konfigurieren.

Memory-Tuning

Speicherverbrauch und Eviction-Policies auf die tatsächliche Shop-Last abstimmen.

High-Availability-Setup

Redis Sentinel oder Cluster für ausfallsichere Magento-Umgebungen einrichten.

10. Zusammenfassung

RedisJSON: Das Wichtigste auf einen Blick

Datentyp

Eigener JSON-Dokumenttyp mit Baumstruktur statt serialisiertem String

Kernbefehle

JSON.SET, JSON.GET, JSON.NUMINCRBY, JSON.ARRAPPEND mit JSONPath-Adressierung

Typischer Einsatz

Verschachtelte Konfigurationsdaten mit häufigen Teil-Updates, etwa Produktvarianten

Grenzen

Zusätzlicher Speicher-Overhead pro Knoten, erfordert Redis Stack oder eigenes Modul

11. FAQ: RedisJSON: Das Wichtigste auf einen Blick

1Ist RedisJSON Teil des Standard-Redis-Servers?
Nein, RedisJSON ist ein separates Modul, das entweder über Redis Stack, Redis Enterprise oder eine manuell geladene .so-Datei bereitgestellt werden muss. Ein Standard-Redis-Server ohne geladenes Modul kennt die JSON.*-Befehle nicht und quittiert sie mit einem Fehler.
2Wann lohnt sich RedisJSON gegenüber einem einfachen JSON-String?
Immer dann, wenn häufig nur Teile eines größeren Dokuments gelesen oder geändert werden, etwa einzelne Preis- oder Lagerfelder. Bei kleinen Dokumenten, die ohnehin fast immer komplett gelesen werden, bringt RedisJSON kaum einen Vorteil gegenüber einem simplen String.
3Kann RedisJSON eine Dokumentendatenbank wie MongoDB ersetzen?
Für einfache, key-basierte Zugriffsmuster mit gelegentlicher Filterung über RediSearch ja, für komplexe Aggregationspipelines, Transaktionen über mehrere Dokumente hinweg oder ein ausgereiftes Schema-Management ist eine dedizierte Dokumentendatenbank in der Regel die robustere Wahl.
4Wie werden JSONPath-Ausdrücke in RedisJSON adressiert?
Über die Standard-JSONPath-Notation mit dem Wurzelzeichen $, gefolgt von Punktnotation für Objektfelder und eckigen Klammern für Array-Indizes, etwa $.lager.reserviert oder $.varianten[0].
5Sind Schreibzugriffe auf einzelne Pfade wirklich atomar?
Ja, jede JSON.*-Operation wird wie jeder andere Redis-Befehl im Single-Threaded-Command-Loop verarbeitet und läuft dadurch vollständig isoliert gegenüber anderen parallelen Befehlen ab.
6Wie wirkt sich RedisJSON auf den Speicherverbrauch aus?
Die interne Baumstruktur benötigt pro verschachteltem Knoten zusätzlichen Verwaltungs-Overhead gegenüber einem komprimierten String. Bei sehr vielen kleinen, tief verschachtelten Dokumenten sollte der tatsächliche Speicherbedarf vorab mit MEMORY USAGE gemessen werden.
7Funktioniert RedisJSON mit Redis Cluster?
Ja, RedisJSON-Dokumente verhalten sich wie jeder andere Key hinsichtlich Hash-Slot-Zuordnung und lassen sich in einem Redis Cluster genauso shardnen wie Strings oder Hashes.
8Wie greift man aus PHP beziehungsweise Magento auf RedisJSON zu?
Über phpredis mit RedisJSON-Unterstützung oder über generische Command-Aufrufe in Predis. Für Magento-Standardfunktionen wie Cache oder Session ist RedisJSON nicht relevant, es eignet sich eher für eigene, zusätzliche Datenstrukturen.
9Werden RedisJSON-Dokumente genauso persistiert wie andere Redis-Daten?
Ja, sie durchlaufen dieselbe RDB- und AOF-Persistenz wie jeder andere Datentyp, es gibt keine gesonderte Konfiguration speziell für JSON-Dokumente.
10Was passiert, wenn ein JSONPath in einem Dokument nicht existiert?
JSON.GET liefert für einen nicht vorhandenen Pfad ein leeres Ergebnis oder einen Fehler zurück, abhängig von der genutzten Pfadsyntax. Vor Schreibzugriffen auf tief verschachtelte, möglicherweise fehlende Pfade lohnt sich deshalb eine vorherige Existenzprüfung mit JSON.TYPE.