Einführung
In diesem Lab werden Sie Redis Lua Scripting erkunden, wobei der Schwerpunkt auf der direkten Ausführung von Lua-Skripten innerhalb von Redis liegt, um komplexe Operationen effizient durchzuführen. Dieses Lab behandelt die Verwendung des Befehls EVAL zur Ausführung von Skripten, das Übergeben von Argumenten an Skripte, das Laden von Skripten mit SCRIPT LOAD und das Ausführen geladener Skripte mit EVALSHA.
Wir beginnen mit der Ausführung eines einfachen Lua-Skripts, das einen Redis-Zähler mit EVAL inkrementiert. Dies demonstriert, wie man das Skript, die Anzahl der Schlüssel (Keys), auf die es zugreift, und die Schlüsselnamen angibt. Anschließend lernen wir, wie man Skripte in Redis lädt und sie mit ihrem SHA1-Hash ausführt, wodurch die Leistung verbessert wird, da die wiederholte Skriptübertragung vermieden wird.
Lua-Skript mit EVAL ausführen
In diesem Schritt werden wir untersuchen, wie man Lua-Skripte direkt in Redis mit dem Befehl EVAL ausführt. Dies ermöglicht es Ihnen, komplexe Operationen an Ihren Daten in einer einzigen Anfrage durchzuführen, wodurch die Netzwerklatenz reduziert und die Leistung verbessert wird.
Bevor wir beginnen, wollen wir die Grundlagen von EVAL verstehen. Der Befehl EVAL benötigt zwei Hauptargumente:
- Das Lua-Skript selbst, als Zeichenkette (String).
- Die Anzahl der Schlüssel (Keys), auf die das Skript zugreift, gefolgt von den tatsächlichen Schlüsselnamen und allen zusätzlichen Argumenten, die Sie an das Skript übergeben möchten.
Hier ist ein einfaches Beispiel, um Ihnen den Einstieg zu erleichtern. Wir erstellen ein Lua-Skript, das einen Redis-Zähler inkrementiert und den neuen Wert zurückgibt.
Öffnen Sie Ihr Terminal und verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (
redis-cli).redis-cliFühren wir nun ein Lua-Skript mit
EVALaus. Dieses Skript inkrementiert einen Zähler namensmycounterund gibt den inkrementierten Wert zurück.EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounterLassen Sie uns diesen Befehl aufschlüsseln:
EVAL "local current = redis.call('INCR', KEYS[1]); return current": Dies ist das Lua-Skript selbst. Es verwendetredis.call('INCR', KEYS[1]), um den Wert des Schlüssels zu inkrementieren, der inKEYS[1]angegeben ist. Das ArrayKEYSenthält die Schlüsselnamen, die an das Skript übergeben werden. Schließlich gibt es den inkrementierten Wert zurück.1: Dies gibt an, dass das Skript auf einen Schlüssel zugreift.mycounter: Dies ist der Name des Schlüssels, auf den das Skript zugreift.
Sie sollten eine ähnliche Ausgabe wie diese sehen:
(integer) 1Wenn Sie denselben Befehl erneut ausführen, sehen Sie, wie der Zähler inkrementiert wird:
EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounterAusgabe:
(integer) 2Überprüfen wir den Wert des Schlüssels
mycountermit dem BefehlGET:GET mycounterAusgabe:
"2"Wie Sie sehen, hat das Lua-Skript den Zähler erfolgreich inkrementiert.
Probieren wir nun ein weiteres Beispiel aus. Dieses Mal erstellen wir ein Skript, das einen Schlüssel auf einen bestimmten Wert setzt, falls er noch nicht existiert.
EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalueIn diesem Befehl:
EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end": Dies ist das Lua-Skript. Es prüft, ob der SchlüsselKEYS[1]existiert. Wenn dies nicht der Fall ist, setzt es den Schlüssel auf den WertARGV[1]und gibt1zurück. Andernfalls gibt es0zurück.1: Dies gibt an, dass das Skript auf einen Schlüssel zugreift.mykey: Dies ist der Name des Schlüssels.myvalue: Dies ist der Wert, der gesetzt werden soll, falls der Schlüssel nicht existiert.
Sie sollten eine ähnliche Ausgabe wie diese sehen:
(integer) 1Dies zeigt an, dass der Schlüssel
mykeyaufmyvaluegesetzt wurde.Überprüfen wir den Wert von
mykey:GET mykeyAusgabe:
"myvalue"Wenn Sie den Befehl
EVALerneut ausführen:EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalueAusgabe:
(integer) 0Dieses Mal gab das Skript
0zurück, da der Schlüssel bereits existierte.Beenden Sie
redis-cli. Dies ist wichtig, damit die Änderungen protokolliert werden.exit
Argumente mit EVAL an Skript übergeben
Im vorherigen Schritt haben wir gelernt, wie man Lua-Skripte mit EVAL ausführt und auf Schlüssel (Keys) zugreift. Lassen Sie uns nun untersuchen, wie man Argumente an diese Skripte übergibt. Dies ermöglicht dynamischere und wiederverwendbare Skripte.
Erinnern Sie sich, dass der Befehl EVAL die folgenden Argumente entgegennimmt:
- Das Lua-Skript selbst, als Zeichenkette (String).
- Die Anzahl der Schlüssel, auf die das Skript zugreift.
- Die Schlüsselnamen.
- Alle zusätzlichen Argumente, die Sie an das Skript übergeben möchten. Auf diese Argumente wird innerhalb des Lua-Skripts über das Array
ARGVzugegriffen.
Beginnen wir mit einem Beispiel. Wir erstellen ein Lua-Skript, das einen Wert zu einem Redis-Zähler hinzufügt. Der Schlüssel des Zählers und der hinzuzufügende Wert werden als Argumente übergeben.
Verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (
redis-cli).redis-cliFühren wir nun ein Lua-Skript mit
EVALaus, das einen Zähler um einen bestimmten Betrag erhöht.EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current" 1 mycounter 5Lassen Sie uns diesen Befehl aufschlüsseln:
EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current": Dies ist das Lua-Skript. Es verwendetredis.call('INCRBY', KEYS[1], ARGV[1]), um den Wert des Schlüssels, der inKEYS[1]angegeben ist, um den inARGV[1]angegebenen Betrag zu erhöhen.1: Dies gibt an, dass das Skript auf einen Schlüssel zugreift.mycounter: Dies ist der Name des Schlüssels, auf den das Skript zugreift.5: Dies ist das Argument, das an das Skript übergeben und alsARGV[1]aufgerufen wird.
Sie sollten eine ähnliche Ausgabe wie diese sehen (vorausgesetzt,
mycounterwar aus dem vorherigen Schritt bei 2):(integer) 7Das Skript hat den Schlüssel
mycounterum 5 erhöht.Überprüfen wir den Wert des Schlüssels
mycountermit dem BefehlGET:GET mycounterAusgabe:
"7"Probieren wir nun ein weiteres Beispiel mit Zeichenkettenargumenten (String Arguments). Wir erstellen ein Skript, das einen Schlüssel auf einen Wert setzt, wobei sowohl der Schlüssel als auch der Wert als Argumente übergeben werden.
EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]" 1 mynewkey mynewvalueIn diesem Befehl:
EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]": Dies ist das Lua-Skript. Es setzt den SchlüsselKEYS[1]auf den WertARGV[1]und gibt den Wert zurück.1: Dies gibt an, dass das Skript auf einen Schlüssel zugreift.mynewkey: Dies ist der Name des Schlüssels.mynewvalue: Dies ist der Wert, der gesetzt werden soll.
Sie sollten eine ähnliche Ausgabe wie diese sehen:
"mynewvalue"Überprüfen wir den Wert von
mynewkey:GET mynewkeyAusgabe:
"mynewvalue"Das Skript hat den Schlüssel
mynewkeyerfolgreich auf den Wertmynewvaluegesetzt.Sie können mehrere Argumente an das Skript übergeben. Erstellen wir beispielsweise ein Skript, das zwei als Argumente übergebene Zeichenketten (Strings) verkettet und das Ergebnis auf einen Schlüssel setzt.
EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result" 1 combinedkey hello worldIn diesem Befehl:
EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result": Dies ist das Lua-Skript. Es verkettetARGV[1]undARGV[2]mit dem Operator.., setzt den SchlüsselKEYS[1]auf das Ergebnis und gibt das Ergebnis zurück.1: Dies gibt an, dass das Skript auf einen Schlüssel zugreift.combinedkey: Dies ist der Name des Schlüssels.hello: Dies ist das erste Zeichenkettenargument (String Argument).world: Dies ist das zweite Zeichenkettenargument (String Argument).
Sie sollten eine ähnliche Ausgabe wie diese sehen:
"helloworld"Überprüfen wir den Wert von
combinedkey:GET combinedkeyAusgabe:
"helloworld"Beenden Sie
redis-cli. Dies ist wichtig, damit die Änderungen protokolliert werden.exit
Skript mit SCRIPT LOAD laden
In den vorherigen Schritten haben wir Lua-Skripte direkt mit dem Befehl EVAL ausgeführt. Dies ist zwar für einfache Skripte nützlich, kann aber für größere, komplexere Skripte umständlich werden. Redis bietet den Befehl SCRIPT LOAD, um Skripte in den Skript-Cache des Redis-Servers zu laden. Dies ermöglicht es Ihnen, das Skript mehrmals auszuführen, ohne das gesamte Skript jedes Mal senden zu müssen, was die Leistung verbessert.
Der Befehl SCRIPT LOAD benötigt ein einzelnes Argument: das Lua-Skript selbst. Er gibt den SHA1-Hash des Skripts zurück, den Sie dann verwenden können, um das Skript mit dem Befehl EVALSHA auszuführen (den wir im nächsten Schritt behandeln werden).
Sehen wir uns an, wie es funktioniert.
Verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (
redis-cli).redis-cliLaden wir nun ein Lua-Skript mit
SCRIPT LOAD. Wir verwenden dasselbe Skript aus dem vorherigen Schritt, das einen Zähler um einen bestimmten Betrag erhöht.SCRIPT LOAD "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current"Dieser Befehl lädt das Skript in den Skript-Cache des Redis-Servers und gibt den SHA1-Hash des Skripts zurück. Sie sollten eine ähnliche Ausgabe wie diese sehen:
"6b1e8dd2999cb08546e74339c0c9489f9f89a84b"Dies ist der SHA1-Hash des Skripts. Notieren Sie sich diesen Hash, da Sie ihn im nächsten Schritt benötigen. Der genaue Hash-Wert kann abweichen.
Laden wir nun das Skript, das einen Schlüssel auf einen Wert setzt, wobei sowohl der Schlüssel als auch der Wert als Argumente übergeben werden.
SCRIPT LOAD "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]"Sie sollten eine ähnliche Ausgabe wie diese sehen:
"a8b2b3648969459a8198262a9166e945e890987c"Notieren Sie sich auch diesen Hash.
Laden wir das Skript, das zwei als Argumente übergebene Zeichenketten (Strings) verkettet und das Ergebnis auf einen Schlüssel setzt.
SCRIPT LOAD "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result"Sie sollten eine ähnliche Ausgabe wie diese sehen:
"d2a800a974ca96849295220424f9a0664a495345"Notieren Sie sich auch diesen Hash.
Sie können überprüfen, ob die Skripte geladen sind, indem Sie den Befehl
SCRIPT EXISTSverwenden. Dieser Befehl nimmt einen oder mehrere SHA1-Hashes als Argumente entgegen und gibt ein Array von 0en und 1en zurück, wobei 1 angibt, dass das Skript mit dem entsprechenden Hash geladen ist, und 0 angibt, dass es nicht geladen ist.Um beispielsweise zu überprüfen, ob das erste Skript, das wir geladen haben, noch geladen ist, verwenden Sie den folgenden Befehl und ersetzen Sie den Hash durch den, den Sie in Schritt 2 erhalten haben:
SCRIPT EXISTS 6b1e8dd2999cb08546e74339c0c9489f9f89a84bAusgabe:
1) (integer) 1Dies zeigt an, dass das Skript geladen ist.
Wenn Sie versuchen, nach einem Skript zu suchen, das nicht geladen ist:
SCRIPT EXISTS 0000000000000000000000000000000000000000Ausgabe:
1) (integer) 0Dies zeigt an, dass das Skript nicht geladen ist.
Beenden Sie
redis-cli. Dies ist wichtig, damit die Änderungen protokolliert werden.exit
Geladenes Skript mit EVALSHA ausführen
Im vorherigen Schritt haben wir gelernt, wie man Lua-Skripte mit dem Befehl SCRIPT LOAD in den Skript-Cache des Redis-Servers lädt. Nun lernen wir, wie man diese geladenen Skripte mit dem Befehl EVALSHA ausführt.
Der Befehl EVALSHA benötigt die folgenden Argumente:
- Der SHA1-Hash des geladenen Skripts.
- Die Anzahl der Schlüssel (Keys), auf die das Skript zugreift.
- Die Schlüsselnamen.
- Alle zusätzlichen Argumente, die Sie an das Skript übergeben möchten.
Die Verwendung von EVALSHA ist effizienter als EVAL, wenn Sie dasselbe Skript mehrmals ausführen müssen, da es vermeidet, das gesamte Skript jedes Mal an den Server zu senden.
Sehen wir uns an, wie es funktioniert.
Verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (
redis-cli).redis-cliFühren wir nun das Lua-Skript aus, das einen Zähler um einen bestimmten Betrag erhöht, indem wir
EVALSHAverwenden. Erinnern Sie sich an den SHA1-Hash, den Sie im vorherigen Schritt für das Skriptlocal current = redis.call('INCRBY', KEYS[1], ARGV[1]); return currenterhalten haben? Wenn nicht, müssen Sie das Skript erneut mitSCRIPT LOADladen. Für dieses Beispiel gehen wir davon aus, dass der Hash6b1e8dd2999cb08546e74339c0c9489f9f89a84bist.EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b 1 mycounter 5Lassen Sie uns diesen Befehl aufschlüsseln:
EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b: Dies gibt an, dass wir das Skript mit dem SHA1-Hash6b1e8dd2999cb08546e74339c0c9489f9f89a84bausführen möchten.1: Dies gibt an, dass das Skript auf einen Schlüssel zugreift.mycounter: Dies ist der Name des Schlüssels, auf den das Skript zugreift.5: Dies ist das Argument, das an das Skript übergeben und alsARGV[1]aufgerufen wird.
Sie sollten eine ähnliche Ausgabe wie diese sehen (vorausgesetzt,
mycounterwar aus dem vorherigen Schritt bei 7):(integer) 12Das Skript hat den Schlüssel
mycounterum 5 erhöht.Überprüfen wir den Wert des Schlüssels
mycountermit dem BefehlGET:GET mycounterAusgabe:
"12"Führen wir nun das Skript aus, das einen Schlüssel auf einen Wert setzt, indem wir
EVALSHAverwenden. Erinnern Sie sich an den SHA1-Hash, den Sie im vorherigen Schritt für das Skriptredis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]erhalten haben? Wenn nicht, müssen Sie das Skript erneut mitSCRIPT LOADladen. Für dieses Beispiel gehen wir davon aus, dass der Hasha8b2b3648969459a8198262a9166e945e890987cist.EVALSHA a8b2b3648969459a8198262a9166e945e890987c 1 anotherkey anothervalueSie sollten eine ähnliche Ausgabe wie diese sehen:
"anothervalue"Überprüfen wir den Wert von
anotherkey:GET anotherkeyAusgabe:
"anothervalue"Wenn Sie versuchen, ein Skript mit einem ungültigen SHA1-Hash auszuführen, erhalten Sie eine Fehlermeldung:
EVALSHA 0000000000000000000000000000000000000000 1 mykey myvalueAusgabe:
(error) NOSCRIPT No matching script. Please use EVAL.Dies zeigt an, dass das Skript mit dem angegebenen SHA1-Hash nicht geladen ist.
Beenden Sie
redis-cli. Dies ist wichtig, damit die Änderungen protokolliert werden.exit
Zusammenfassung
In diesem Lab haben Sie die Lua-Skripterstellung (Lua scripting) in Redis erkundet, wobei der Schwerpunkt auf der direkten Ausführung von Skripten mit dem Befehl EVAL lag. Wir haben gelernt, dass EVAL das Lua-Skript als Zeichenkette (String), die Anzahl der aufgerufenen Schlüssel (Keys) und die Schlüsselnamen selbst als Argumente entgegennimmt. Wir haben geübt, einen Redis-Zähler mit einem Lua-Skript innerhalb von EVAL zu erhöhen, und beobachtet, wie das Skript auf den angegebenen Schlüssel zugreift und ihn verändert.
Darüber hinaus haben wir gelernt, wie man Argumente an Lua-Skripte übergibt, Skripte mit SCRIPT LOAD in Redis lädt und geladene Skripte mit EVALSHA ausführt. Denken Sie daran, redis-cli nach jedem Schritt zu beenden, um sicherzustellen, dass Ihre Befehle korrekt protokolliert werden. Dies ermöglicht eine effizientere Ausführung komplexer Skripte.


