Redis Lua Scripts für atomare Operationen richtig einsetzen

Redis Lua Scripts führen mehrere Redis-Befehle samt Bedingungen isoliert auf dem Server aus. So entsteht zwischen Lesen, Prüfen und Schreiben kein widersprüchlicher Zwischenstand durch andere Clients. Atomar bedeutet dabei nicht automatisches Rollback: Eingaben und Fehlerpfade müssen vor allem vor Schreiboperationen bewusst entworfen werden. Entscheidend sind klar deklarierte Keys, stabile Rückgabewerte, kurze Laufzeiten und ein passendes Modell – vom nativen Befehl bis zur Redis Function.

Atomare Redis Lua Scripts einordnen

Redis Lua Scripts führen fachliche Datenlogik direkt im Redis-Server aus. Während ein Script läuft, verarbeitet Redis keine anderen Serveraktivitäten; die enthaltenen Befehle sind daher gegenüber anderen Clients isoliert. Damit lassen sich mehrere einfache Kommandos zu einer atomaren Operation verbinden, etwa eine Limitprüfung mit anschließendem Zähler-Update oder eine Abbuchung nur bei ausreichendem Guthaben.

Ohne Script kann ein Client zunächst mit GET einen Zähler lesen, die Grenze im Anwendungscode prüfen und danach INCR senden. Zwischen diesen Schritten kann jedoch ein anderer Client denselben Zähler verändern. Ein Script liest, prüft und erhöht dagegen ohne diesen beobachtbaren Zwischenzustand. Das löst die Race Condition der zusammengesetzten Regel, nicht aber automatisch Fragen wie passende Grenzwerte, Ablaufzeiten oder Rückgabeformate.

Atomar und isoliert bedeutet nicht, dass Redis Lua Scripts Datenbanktransaktionen mit automatischem Rollback sind. Tritt nach einer bereits erfolgten Schreiboperation ein Laufzeitfehler auf, werden vorherige Änderungen nicht pauschal zurückgenommen. Deshalb sollten Scripts Eingaben, Datentypen und fachliche Voraussetzungen vor dem ersten Schreiben prüfen; Fehlerpfade nach Änderungen brauchen eine bewusst entworfene Behandlung.

Typische Regeln sind: einen Zugriff nur innerhalb eines Limits zulassen oder einen Bestand nur bei ausreichender Menge reduzieren. Prüfe zunächst, ob ein vorhandener einzelner Redis-Befehl die gesamte Regel bereits ausdrückt. Ein Script ist dann sinnvoll, wenn mehrere Redis-Operationen einschließlich ihrer Bedingungen atomar zusammenwirken müssen.

Ein Lua-Muster für Vergleich-und-Löschen vergleicht den gespeicherten Wert mit einem übergebenen Ownership-Token und löscht nur bei Gleichheit. Dadurch kann ein verspäteter Prozess nicht allein wegen seines alten Tokens einen inzwischen neu belegten Key löschen.

Dieses Vergleichsmuster beschreibt ausschließlich die sichere Reihenfolge für einen einzelnen Redis-Key. Es löst nicht die weitergehenden Fragen verteilter Sperren, etwa passende Lease-Dauern, Prozesspausen, Ausfälle oder die Koordination mehrerer Redis-Instanzen. Die Atomizität eines Befehls oder Scripts umfasst zudem nur die beteiligten Redis-Daten, nicht Zahlung, Datenbank, E-Mail oder externe APIs.

Lua Sandbox und klare Grenzen

Redis Open Source bettet für Scripts Lua 5.1 ein. Diese Laufzeit ist nicht mit einer lokal installierten oder aktuellen Lua-Hauptversion gleichzusetzen: Verfügbarer Sprachumfang und Sicherheitsregeln bestimmt Redis. Wer redis lua scripts entwickelt, sollte sie deshalb gegen die tatsächlich eingesetzte Redis-Version prüfen und nicht Eigenschaften einer beliebigen externen Lua-Umgebung voraussetzen.

Die Ausführung erfolgt in einer Sandbox mit absichtlich engen Grenzen. Ein Script soll Redis-Daten und übergebene Argumente verarbeiten, aber weder Dateisystem, Netzwerk noch Betriebssystemdienste nutzen. Externe HTTP-Aufrufe, das Versenden von Nachrichten oder der Zugriff auf lokale Dateien gehören daher in den Anwendungscode oder einen dafür vorgesehenen Dienst, nicht in cache scripting.

Redis stellt KEYS und ARGV als globale Laufzeitvariablen bereit. Für eigene Zwischenwerte und Hilfsfunktionen verwendest du dagegen lokale Variablen mit local. So bleibt erkennbar, welche Werte nur für diesen Aufruf gelten, und die Script-Logik erzeugt keine vermeidbaren Abhängigkeiten. Redis-Kommandos rufst du gezielt über redis.call oder redis.pcall auf.

Die Sandbox ersetzt keine Kapazitätsplanung. Während regulärer Ausführung blockiert ein Script andere Clients am Server, daher sind lange Schleifen, unbeschränkte Datenmengen und rechenintensive Auswertungen ungeeignet. Beschränke die Arbeit auf wenige, vorher bekannte Keys und kleine Berechnungen. Umfangreiche Analysen, SCAN-basierte Gesamtbestände oder Kommunikation mit Fremdsystemen würden die Betriebsrisiken erhöhen, ohne die Atomizität sinnvoll zu erweitern.

EVAL, KEYS und ARGV verstehen

Der unmittelbare Aufruf eines Scripts verwendet die Form EVAL script numkeys [key …] [arg …]. Nach dem Quelltext legt numkeys fest, wie viele folgende Parameter Schlüssel sind. Das Script erreicht sie über KEYS mit einsbasierter Indexierung; alle weiteren Werte stehen in ARGV. Diese Trennung ist wesentlich: Schlüssel beschreiben die Redis-Daten, Argumente die fachlichen Eingaben wie Grenzwert, Betrag oder erwarteten Token.

Ein Limit-Script erhält beispielsweise den Zähler als KEYS[1] und den Höchstwert als ARGV[1]. Es liest den aktuellen Stand, wandelt den Grenzwert mit tonumber(ARGV[1]) in eine Zahl um und vergleicht beide Werte, bevor es erhöht. Die Umwandlung macht die beabsichtigte numerische Fachregel explizit, statt sich auf eine implizite Behandlung von Argumentwerten zu verlassen. Fehlt ein Zähler, kann das Script den gelesenen Wert gezielt als null behandeln.

Konzeptionelle Trennung von Redis-Schlüsseln und Argumentwerten bei einem Lua Script.
Keys und fachliche Argumente folgen getrennten Wegen in die serverseitige Logik.

Jeder Key, den das Script liest oder schreibt, muss vorab als Key-Argument angegeben werden. Key-Namen im Script aus Präfixen zusammenzusetzen oder aus gespeicherten Daten abzuleiten, ist kein belastbares Muster. Redis kann dann insbesondere bei Redis Open Source mit aktiviertem Cluster nicht vor der Ausführung nachvollziehen, welche Daten das Script benötigt. Übergib daher bekannte Schlüssel vollständig über KEYS und variable Fachwerte ausschließlich über ARGV.

Bei Redis Open Source mit aktiviertem Cluster müssen die einem Script übergebenen Keys außerdem im selben Hash Slot liegen. Die vorherige Deklaration ermöglicht diese Prüfung, ersetzt sie aber nicht. Für zusammengehörige Daten kann ein bewusst gewählter Hash Tag helfen, etwa account:{4711}:balance und account:{4711}:reservations. Der Teil in geschweiften Klammern bestimmt hier die Slot-Zuordnung; dynamisch ermittelte Keys würden diese Planung unterlaufen.

Fixed-Window-Zähler atomar aktualisieren

Das folgende Beispiel ist ein atomarer Fixed-Window-Zähler für eine lokale Testinstanz. Es prüft Zählerstand und Grenze in einem Serverlauf und setzt die Ablaufzeit nur beim ersten erfolgreichen Zugriff des Zeitfensters. Damit entfällt das Zeitfenster zwischen einem GET im Anwendungscode und einem späteren INCR, in dem ein anderer Client den Zähler verändern könnte.

Der Aufruf übergibt den Zähler-Key, das Limit und die Fensterdauer in Sekunden. Status 1 bedeutet zugelassen, Status 0 bedeutet Limit erreicht. Status 2 meldet eine von den Vorprüfungen erkannte ungültige Eingabe, einen dort abgelehnten String-Zählerwert oder einen vorhandenen String-Zähler ohne TTL. Enthält der Key einen anderen Redis-Datentyp, scheitert bereits GET mit einem technischen Typfehler; das Script liefert dann keinen Status 2. Auch andere Redis-Laufzeitfehler sind vom fachlichen Rückgabestatus zu unterscheiden. Das Beispiel ist keine Vorlage für Zugangsdaten, produktive Limits oder Lasttests.

Vor jeder Schreiboperation validiert das Script alle Zahlen als endliche positive Ganzzahlen innerhalb einer bewusst kleinen Obergrenze. Das ist mehr als eine Prüfung mit tonumber: Werte wie 1.5 oder 1e3 werden abgelehnt. Die Grenze von einer Million verhindert zudem, dass Lua-Zahlenpräzision oder der von INCR erwartete Integer-String außerhalb des Beispielsbereichs relevant werden. Die maximale Fensterdauer von 86.400 Sekunden begrenzt auch die an EXPIRE übergebene Sekundenzahl.

Code
EVAL "local max_counter = 1000000; local max_window = 86400; local function positive_integer(value, maximum) if type(value) ~= 'string' or not string.match(value, '^%d+$') then return nil; end; local number = tonumber(value); if not number or number ~= math.floor(number) or number < 1 or number > maximum then return nil; end; return number; end; local limit = positive_integer(ARGV[1], max_counter); local window = positive_integer(ARGV[2], max_window); if not limit or not window then return {2, 'invalid-arguments'}; end; local raw = redis.call('GET', KEYS[1]); if raw and (type(raw) ~= 'string' or not string.match(raw, '^%d+$')) then return {2, 'invalid-counter'}; end; local current = raw and tonumber(raw) or 0; if not current or current ~= math.floor(current) or current < 0 or current > max_counter then return {2, 'invalid-counter'}; end; if raw and redis.call('TTL', KEYS[1]) == -1 then return {2, 'missing-ttl'}; end; if current >= limit then return {0, current}; end; local next = redis.call('INCR', KEYS[1]); if next == 1 then redis.call('EXPIRE', KEYS[1], window); end; return {1, next}" 1 demo:rate-limit 3 60

Der reguläre Ausdruck akzeptiert nur dezimale Ziffern; anschließend prüft die Hilfsfunktion den Zahlenwert, die Ganzzahligkeit und die Obergrenze. Ein bereits vorhandener Zähler darf nur ein nichtnegativer Ganzzahlwert im selben begrenzten Bereich sein. Dadurch kann ein negativer, gebrochener oder übergroßer Wert die Limitsemantik nicht unbemerkt verändern. Erst nach diesen Prüfungen folgt INCR.

Ist der Key nicht vorhanden, beginnt das Script bei 0. Existiert bereits ein gültiger String-Zähler ohne Ablaufzeit, liefert es Status 2 und schreibt nichts. Nach dem ersten INCR setzt EXPIRE die zuvor vollständig geprüfte TTL. Bei späteren Treffern bleibt sie unverändert, sodass das Fenster nicht fortlaufend verlängert wird.

Der Rückgabevertrag ist Teil der Schnittstelle: Das erste Array-Element beschreibt den Status, das zweite liefert je nach Status den Zählerstand oder eine Fehlerkennung. Der aufrufende Code sollte eine fachliche Ablehnung mit Status 0 anders behandeln als Status 2, der auf eine verletzte Voraussetzung hinweist. Für weitere Informationen zur Wahl und Beobachtung von Ablaufzeiten ist der Artikel Redis Key Expiration analysieren und optimieren eine ergänzende Grundlage.

Die TTL wird hier bewusst nur beim ersten Treffer gesetzt. Ein Muster, das sie bei jedem Zugriff erneuert, hätte eine andere Zeitsemantik und wäre kein Fixed Window mehr. Lua-Atomizität beseitigt nur die Race Condition. Ob Fixed Window, Sliding Window oder Token Bucket zur gewünschten Fairness und Lastverteilung passt, entscheidet der gewählte Algorithmus, nicht die Scriptsprache.

Passendes Atomizitätsmodell auswählen

Nicht jede zusammengesetzte Anforderung benötigt ein Script. Existiert ein einzelner Redis-Befehl, der die Fachregel bereits vollständig ausdrückt, ist er meist einfacher zu betreiben und zu prüfen. Für mehrstufige Regeln müssen dagegen Bedingungen, Datentypen und Rückgabevertrag gemeinsam betrachtet werden.

Ab Redis Open Source 8.4 gibt es native Compare-and-Set- und Compare-and-Delete-Operationen für einzelne String-Keys: SET unterstützt die Vergleichsoptionen IFEQ/IFNE/IFDEQ/IFDNE; DELEX übernimmt bedingtes Löschen. Für passende Einzel-Key-Fälle ist damit kein eigenes Vergleichsscript erforderlich. In Redis 8.2, 8.0 und 7.x stehen diese neuen SET-Optionen und DELEX nicht zur Verfügung; dort bleiben passende WATCH- oder Lua-Muster relevant.

Für optimistisches Compare-and-Set kann WATCH vor MULTI und EXEC passend sein: Ändert ein beobachteter Key sich vor EXEC, wird die Transaktion abgebrochen, und der Client entscheidet über einen erneuten Versuch. Auch Transaktionen bieten bei Fehlern während EXEC keinen allgemeinen Rollback. WATCH bleibt daher eine Option, wenn die notwendige Bedingung nicht durch einen einzelnen nativen Befehl abgebildet wird.

Atomizitätsmodelle für Redis-Operationen im Vergleich
ModellGeeigneter EinsatzfallCode und AufrufNach Neustart oder FailoverClient-Verhalten und Grenze
Nativer BefehlEine vorhandene Einzeloperation bildet die Regel abKein Programmcode; direkter BefehlKein Script-Cache betroffenKeine Script-Nachladung; auf vorhandene Semantik begrenzt
Native CAS/CAD ab Redis Open Source 8.4Wertabhängiges Setzen oder Löschen eines einzelnen String-KeysSET mit IFEQ/IFNE/IFDEQ/IFDNE; DELEX mit VergleichsbedingungKein Script-Cache betroffenVersionsgrenze und Vergleichsbedingung prüfen; keine zusammengesetzte Mehr-Key-Regel
MULTI/EXEC mit WATCHOptimistisches Lesen, Prüfen und SchreibenWATCH, MULTI, EXECKein ProgrammspeicherBei Änderung vor EXEC erneut lesen und entscheiden; kein Rollback bei EXEC-Fehlern
EVALKleines, unmittelbar aufgerufenes ScriptQuelltext bei jedem EVALScript-Cache ist nicht dauerhaftKeine Digest-Nachladung; Quelltext wird wieder übertragen
SCRIPT LOAD plus EVALSHAWiederverwendetes Script mit bekanntem DigestLaden, danach Aufruf per SHA1-DigestCache kann fehlenNOSCRIPT behandeln und erneut laden; Pipeline-Fallback besonders planen
Redis Functions ab 7.0Benannte, wiederverwendbare DatenlogikFUNCTION LOAD, danach FCALLBibliotheken werden repliziert und persistiertVersions- und Bereitstellungsprozess nötig; nicht mit EVAL gleichsetzen

EVAL-Scripts sind an den Script-Cache gebunden und erhalten ihre Eingaben über KEYS und ARGV. Redis Functions gibt es ab Redis 7.0 als benannte Bibliotheken: Sie werden mit FUNCTION LOAD registriert, mit FCALL aufgerufen sowie zusammen mit der Datenbank persistiert und repliziert. Ihre Schlüssel und Argumente erreichen die Funktion als Parameter; daraus folgt ein anderes Bereitstellungs- und Aufrufmodell als bei EVAL.

Für anwendungsnahe, kleine Logik ist EVAL daher ein direkter Einstieg. Mehrere Clients und langfristig gepflegte Datenlogik sprechen häufig für Functions, sofern die eingesetzte Redis-Open-Source-Version sie unterstützt. Die Entscheidung sollte außerdem Deployment, Berechtigungen, Fehlerbehandlung und eine eindeutig dokumentierte Rückgabe berücksichtigen, nicht nur die Zahl der Redis-Befehle.

Cluster, Fehler und Rückgabeverträge

Bei Redis Open Source mit aktiviertem Cluster müssen die übergebenen Keys eines Mehr-Key-Scripts im selben Hash Slot liegen. Hash Tags machen das steuerbar: Bei account:{4711}:balance und account:{4711}:reservations bestimmt der Inhalt zwischen geschweiften Klammern den Slot. Beide Keys können deshalb gemeinsam angesprochen werden. Die Same-Slot-Voraussetzung gilt dort auch für die hier betrachteten Mehrschlüsseloperationen und MULTI/EXEC-Transaktionen. Andere Produkt- und Clusterkonfigurationen können bei einzelnen Befehlen abweichen. Daraus folgt keine allgemeine Cross-Slot-Freigabe für Lua: Die Mehrschlüssel-Dokumentation ordnet EVAL/EVALSHA auch bei Redis Software mit aktiviertem Cluster und mit oder ohne OSS Cluster API als Single-Slot-Operation ein.

Alle verwendeten Schlüssel müssen vor dem Aufruf als Key-Argumente deklariert werden. Ein Script darf Key-Namen nicht aus gespeicherten Werten ableiten oder dynamisch zusammensetzen. Diese Regel ermöglicht Redis die korrekte Slot-Prüfung vor der Ausführung und verhindert verdeckte Abhängigkeiten, die in einer Standalone-Instanz unauffällig bleiben, bei Redis Open Source mit aktiviertem Cluster aber scheitern.

Mit redis.call() wird ein Fehler des aufgerufenen Redis-Kommandos als Scriptfehler an den Client weitergegeben. redis.pcall() liefert ihn dagegen an Lua zurück, damit das Script ihn gezielt behandeln kann. pcall ist nur sinnvoll, wenn eine fachliche Reaktion definiert ist, etwa eine sauber strukturierte Fehlerantwort oder ein alternativer zulässiger Ablauf. Fehler still zu ignorieren verschleiert Daten- und Integritätsprobleme.

Ein Fehlervertrag trennt technische Fehler von fachlichen Ergebnissen. WRONGTYPE bedeutet etwa, dass der gespeicherte Redis-Datentyp nicht zum erwarteten Befehl passt und untersucht werden muss. Eine abgelehnte Reservierung wegen fehlenden Bestands ist dagegen ein erwartetes Ergebnis und kann beispielsweise Status und Restbestand zurückgeben. Anwendungen sollten diese Kategorien nicht gleich behandeln oder beide pauschal wiederholen.

Script-Auslieferung robust betreiben

EVAL eignet sich für unmittelbare Aufrufe: Der Client überträgt den vollständigen Lua-Quelltext zusammen mit Key- und Argumentwerten. Für ein häufig verwendetes, unverändertes Script kann die Anwendung es stattdessen mit SCRIPT LOAD in den Script-Cache laden. Redis liefert dafür einen SHA1-Digest zurück; EVALSHA führt anschließend genau den dazugehörigen Quelltext aus. Das spart die wiederholte Übertragung, ändert aber weder die Atomizität noch die fachliche Verantwortung des Scripts.

Der Script-Cache ist nicht dauerhaft. Nach einem Neustart, Failover oder SCRIPT FLUSH kann ein Aufruf per Digest mit NOSCRIPT scheitern. Die Anwendung sollte diesen Fall regulär behandeln: Script erneut laden und den fachlich sicheren Aufruf wiederholen, sofern die eigene Retry-Logik das zulässt. Ein Digest darf daher nicht als Zusage verstanden werden, dass das Script auf jedem Zielserver bereits vorhanden ist.

Bei Pipelines ist dieser Fallback eingeschränkt. Sind mehrere Befehle bereits gemeinsam gesendet, kann die Anwendung einen darin auftretenden NOSCRIPT-Fehler nicht rückwirkend durch Laden und erneutes Ausführen an derselben Stelle ersetzen. Redis empfiehlt für solche Fälle parameterisiertes EVAL als Ausweichstrategie. Wer Replikation und Failover plant, sollte außerdem verstehen, welche Rolle der Replikationspuffer bei der Wiederanbindung einer Replica spielt: Redis Replication Backlog verstehen.

Variable Werte gehören nicht in den Lua-Quelltext, sondern in ARGV. Andernfalls erzeugt etwa jeder Grenzwert ein anderes Script und vergrößert den Cache unnötig. Seit Redis 7.4 können per EVAL oder EVAL_RO geladene Scripts bei einer Cache-Grenze nach LRU entfernt werden; das ersetzt weder Parametrisierung noch die Behandlung von NOSCRIPT.

Lange Scripts und Schreibfehler beherrschen

Ein Lua-Script blockiert während seiner regulären Ausführung andere Serveraktivitäten. Das schafft Isolation, wird bei langen Laufzeiten aber zum Betriebsrisiko. Überschreitet ein Script den konfigurierten busy-reply-threshold, antwortet Redis auf normale Befehle mit BUSY; es beendet das Script nicht automatisch. Beschränke Scripts deshalb auf wenige bekannte Keys und kleine, begrenzte Berechnungen.

Konzeptioneller Vergleich eines kurzen Redis Lua Scripts mit einem langen blockierenden Ablauf.
Kurze, begrenzte Script-Abläufe senken das Risiko blockierter Client-Anfragen.

Schreiboperationen vor einem Fehler oder einer Endlosschleife sind besonders kritisch. Hat ein Script bereits Daten verändert, kann SCRIPT KILL es nicht sicher beenden. Prüfe Eingaben daher vor dem ersten Schreiben und vermeide unbeschränkte Schleifen sowie SCAN über Gesamtbestände. Tests sollten Datenvolumen und Fehlerpfade des geplanten Einsatzes abbilden.

Fehlerfälle bei Redis Lua Scripts und sichere Reaktion der Anwendung
FallErkennbare AntwortTypische UrsacheSichere Konsequenz
NOSCRIPTFehlerantwort NOSCRIPTDigest fehlt im flüchtigen Script-CacheScript laden oder parameterisiertes EVAL verwenden; nur nach eigener Retry-Regel wiederholen.
CROSSSLOTCROSSSLOT bei Redis Open Source mit aktiviertem ClusterDie übergebenen Keys des Scripts liegen in verschiedenen Hash SlotsKey-Design ändern und alle erforderlichen Keys deklarieren.
WRONGTYPERedis-Fehler WRONGTYPEKey besitzt einen unerwarteten DatentypDatenmodell oder Script-Voraussetzung korrigieren; nicht als fachliche Ablehnung behandeln.
Speicherdruck über maxmemorySchreiboperation kann das Script abbrechenRedis liegt beim Start bereits über dem SpeicherlimitNicht blind wiederholen; bei redis.pcall einen sicheren, dokumentierten Fehlerpfad vorsehen.
BUSYFehlerantwort BUSY für andere BefehleScript überschreitet den busy-reply-thresholdLast reduzieren und Script verkleinern; nach Schreibvorgängen nicht auf Killen bauen.
Fachliche AblehnungDokumentierter StatuswertEtwa Limit erreicht oder Bestand zu niedrigStatus auswerten und den Geschäftsvorgang geordnet ablehnen.

Bei maxmemory hängt der Ablauf von der ersten Schreiboperation ab. Liegt Redis bereits über dem Limit, kann ein speicherverbrauchender Befehl bei redis.call das Script abbrechen; redis.pcall liefert den Fehler an Lua zurück und verlangt einen bewusst entworfenen Fehlerpfad. Bereits ausgeführte Änderungen werden dadurch nicht repariert.

Eine erste Operation ohne zusätzlichen Speicherbedarf, etwa DEL oder LREM, kann das Script dagegen weiterlaufen lassen; spätere Schreibvorgänge können den Verbrauch über maxmemory erhöhen. Technische Fehler wie WRONGTYPE oder CROSSSLOT bei Redis Open Source mit aktiviertem Cluster verlangen Korrekturen am Datenmodell beziehungsweise Key-Design, während nur das Script selbst eine fachliche Ablehnung als stabilen Status definieren kann.

Geeignete Einsatzfälle bewusst entscheiden

Für eine bedingte Reservierung kann ein Script Bestand prüfen, einen zu kleinen Wert ablehnen und bei Erfolg den Restbestand zurückgeben. Die atomare Reservierung umfasst jedoch nur Redis. Zahlung, relationale Datenbank, E-Mail und externe APIs benötigen eine eigene Abstimmung und gegebenenfalls Ausgleichslogik.

Die Auswahl hängt von Redis-Version und Datenmodell ab. Ab Redis Open Source 8.4 können die Vergleichsoptionen von SET ein bedingtes Setzen und DELEX das Vergleich-und-Löschen eines einzelnen String-Keys übernehmen. Vor Redis 8.4 oder bei einer komplexeren Bedingung ist WATCH mit MULTI/EXEC eine Alternative: Ändert sich ein beobachteter Key vor EXEC, bricht die Transaktion ab und der Client entscheidet über erneutes Lesen und Wiederholen. Ein kurzes Lua-Script passt, wenn mehrere Befehle oder Datenstrukturen einschließlich ihrer Fachregel serverseitig zusammenwirken müssen.

Für verteilte Sperren genügt weder der einzelne Befehl noch das Lua-Muster als Gesamtkonzept. Lease-Dauer, Prozesspausen, Ausfälle, Wiederholungen, Failover und Mehrinstanzenszenarien bleiben separat zu bewerten. Bevorzuge einen nativen Befehl, wenn die betriebene Version und seine Semantik die gesamte Regel abdecken. Andernfalls sind WATCH und ein kurzes Script je nach Fehlervertrag und Ort der Fachlogik abzuwägen. Für wiederverwendbare serverseitige Logik kann eine Redis Function passen. Read-only-Scripts dürfen ab Redis 7.0 über EVAL_RO oder EVALSHA_RO laufen, aber nur bei garantiert schreibfreier Logik.

Quellen und fachlicher Stand

Recherche-Stand:

Recherche- und Versionsstand: 23. September 2026. Der Artikel behandelt Redis Open Source und unterscheidet EVAL-Scripts von Redis Functions ab Redis 7.0. Versionsgrenzen und verfügbare Befehle vor dem Einsatz gegen die konkret betriebene Redis-Version prüfen.

https://redis.io/docs/latest/develop/programmability/eval-intro/

https://redis.io/docs/latest/develop/programmability/

https://redis.io/docs/latest/commands/eval/

https://redis.io/docs/latest/develop/using-commands/multi-key-operations/

https://redis.io/docs/latest/develop/using-commands/transactions/

https://redis.io/docs/latest/develop/programmability/functions-intro/

https://redis.io/docs/latest/commands/evalsha_ro/

Aktuelle Artikel

Konzeptionelle Darstellung eines isolierten Redis Lua Script-Ablaufs zwischen mehreren Clients und einem konsistenten Schlüsselwert.
Datenbanken

Redis Lua Scripts für atomare Operationen richtig einsetzen

Redis Lua Scripts verbinden Lesen, Prüfen und Schreiben zu einer isolierten Serveroperation. Der Artikel erklärt KEYS und ARGV, EVAL und Functions, Cluster-Grenzen, Fehlerverträge sowie sichere Muster für Limits und Reservierungen.

Konzeptionelle Darstellung eines NGINX Reverse Proxy mit DNS-Resolver-Cache und wechselnden Backend-Adressen.
Plesk Webserver

NGINX Resolver Cache richtig konfigurieren

So konfigurierst du den NGINX-Resolver für dynamische Backends: DNS-TTL, valid, resolver_timeout, variable proxy_pass-Ziele und dynamische Upstreams klar voneinander getrennt.

Konzeptionelle Darstellung von Kernelzuständen, die über procfs sichtbar werden.
Administration

Linux procfs für Administratoren: wichtige Dateien im Überblick

procfs liefert direkte Einblicke in den laufenden Linux-Kernel. Dieser Leitfaden erklärt wichtige Dateien unter /proc, ordnet Zähler und Momentaufnahmen ein und zeigt sichere Diagnosepfade für Last, Speicher, Prozesse, I/O und sysctl-Parameter.