Redis Lua Scripting

RedisBeginner
Jetzt üben

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:

  1. Das Lua-Skript selbst, als Zeichenkette (String).
  2. 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.

  1. Öffnen Sie Ihr Terminal und verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (redis-cli).

    redis-cli
  2. Führen wir nun ein Lua-Skript mit EVAL aus. Dieses Skript inkrementiert einen Zähler namens mycounter und gibt den inkrementierten Wert zurück.

    EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounter

    Lassen Sie uns diesen Befehl aufschlüsseln:

    • EVAL "local current = redis.call('INCR', KEYS[1]); return current": Dies ist das Lua-Skript selbst. Es verwendet redis.call('INCR', KEYS[1]), um den Wert des Schlüssels zu inkrementieren, der in KEYS[1] angegeben ist. Das Array KEYS enthä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) 1

    Wenn 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 mycounter

    Ausgabe:

    (integer) 2
  3. Überprüfen wir den Wert des Schlüssels mycounter mit dem Befehl GET:

    GET mycounter

    Ausgabe:

    "2"

    Wie Sie sehen, hat das Lua-Skript den Zähler erfolgreich inkrementiert.

  4. 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 myvalue

    In 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üssel KEYS[1] existiert. Wenn dies nicht der Fall ist, setzt es den Schlüssel auf den Wert ARGV[1] und gibt 1 zurück. Andernfalls gibt es 0 zurü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) 1

    Dies zeigt an, dass der Schlüssel mykey auf myvalue gesetzt wurde.

  5. Überprüfen wir den Wert von mykey:

    GET mykey

    Ausgabe:

    "myvalue"

    Wenn Sie den Befehl EVAL erneut 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 myvalue

    Ausgabe:

    (integer) 0

    Dieses Mal gab das Skript 0 zurück, da der Schlüssel bereits existierte.

  6. 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:

  1. Das Lua-Skript selbst, als Zeichenkette (String).
  2. Die Anzahl der Schlüssel, auf die das Skript zugreift.
  3. Die Schlüsselnamen.
  4. Alle zusätzlichen Argumente, die Sie an das Skript übergeben möchten. Auf diese Argumente wird innerhalb des Lua-Skripts über das Array ARGV zugegriffen.

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.

  1. Verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (redis-cli).

    redis-cli
  2. Führen wir nun ein Lua-Skript mit EVAL aus, das einen Zähler um einen bestimmten Betrag erhöht.

    EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current" 1 mycounter 5

    Lassen Sie uns diesen Befehl aufschlüsseln:

    • EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current": Dies ist das Lua-Skript. Es verwendet redis.call('INCRBY', KEYS[1], ARGV[1]), um den Wert des Schlüssels, der in KEYS[1] angegeben ist, um den in ARGV[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 als ARGV[1] aufgerufen wird.

    Sie sollten eine ähnliche Ausgabe wie diese sehen (vorausgesetzt, mycounter war aus dem vorherigen Schritt bei 2):

    (integer) 7

    Das Skript hat den Schlüssel mycounter um 5 erhöht.

  3. Überprüfen wir den Wert des Schlüssels mycounter mit dem Befehl GET:

    GET mycounter

    Ausgabe:

    "7"
  4. 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 mynewvalue

    In diesem Befehl:

    • EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]": Dies ist das Lua-Skript. Es setzt den Schlüssel KEYS[1] auf den Wert ARGV[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"
  5. Überprüfen wir den Wert von mynewkey:

    GET mynewkey

    Ausgabe:

    "mynewvalue"

    Das Skript hat den Schlüssel mynewkey erfolgreich auf den Wert mynewvalue gesetzt.

  6. 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 world

    In diesem Befehl:

    • EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result": Dies ist das Lua-Skript. Es verkettet ARGV[1] und ARGV[2] mit dem Operator .., setzt den Schlüssel KEYS[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"
  7. Überprüfen wir den Wert von combinedkey:

    GET combinedkey

    Ausgabe:

    "helloworld"
  8. 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.

  1. Verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (redis-cli).

    redis-cli
  2. Laden 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.

  3. 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.

  4. 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.

  5. Sie können überprüfen, ob die Skripte geladen sind, indem Sie den Befehl SCRIPT EXISTS verwenden. 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 6b1e8dd2999cb08546e74339c0c9489f9f89a84b

    Ausgabe:

    1) (integer) 1

    Dies zeigt an, dass das Skript geladen ist.

    Wenn Sie versuchen, nach einem Skript zu suchen, das nicht geladen ist:

    SCRIPT EXISTS 0000000000000000000000000000000000000000

    Ausgabe:

    1) (integer) 0

    Dies zeigt an, dass das Skript nicht geladen ist.

  6. 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:

  1. Der SHA1-Hash des geladenen Skripts.
  2. Die Anzahl der Schlüssel (Keys), auf die das Skript zugreift.
  3. Die Schlüsselnamen.
  4. 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.

  1. Verbinden Sie sich mit dem Redis-Server über die Redis-Befehlszeilenschnittstelle (redis-cli).

    redis-cli
  2. Führen wir nun das Lua-Skript aus, das einen Zähler um einen bestimmten Betrag erhöht, indem wir EVALSHA verwenden. Erinnern Sie sich an den SHA1-Hash, den Sie im vorherigen Schritt für das Skript local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current erhalten haben? Wenn nicht, müssen Sie das Skript erneut mit SCRIPT LOAD laden. Für dieses Beispiel gehen wir davon aus, dass der Hash 6b1e8dd2999cb08546e74339c0c9489f9f89a84b ist.

    EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b 1 mycounter 5

    Lassen Sie uns diesen Befehl aufschlüsseln:

    • EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b: Dies gibt an, dass wir das Skript mit dem SHA1-Hash 6b1e8dd2999cb08546e74339c0c9489f9f89a84b ausfü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 als ARGV[1] aufgerufen wird.

    Sie sollten eine ähnliche Ausgabe wie diese sehen (vorausgesetzt, mycounter war aus dem vorherigen Schritt bei 7):

    (integer) 12

    Das Skript hat den Schlüssel mycounter um 5 erhöht.

  3. Überprüfen wir den Wert des Schlüssels mycounter mit dem Befehl GET:

    GET mycounter

    Ausgabe:

    "12"
  4. Führen wir nun das Skript aus, das einen Schlüssel auf einen Wert setzt, indem wir EVALSHA verwenden. Erinnern Sie sich an den SHA1-Hash, den Sie im vorherigen Schritt für das Skript redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1] erhalten haben? Wenn nicht, müssen Sie das Skript erneut mit SCRIPT LOAD laden. Für dieses Beispiel gehen wir davon aus, dass der Hash a8b2b3648969459a8198262a9166e945e890987c ist.

    EVALSHA a8b2b3648969459a8198262a9166e945e890987c 1 anotherkey anothervalue

    Sie sollten eine ähnliche Ausgabe wie diese sehen:

    "anothervalue"
  5. Überprüfen wir den Wert von anotherkey:

    GET anotherkey

    Ausgabe:

    "anothervalue"
  6. Wenn Sie versuchen, ein Skript mit einem ungültigen SHA1-Hash auszuführen, erhalten Sie eine Fehlermeldung:

    EVALSHA 0000000000000000000000000000000000000000 1 mykey myvalue

    Ausgabe:

    (error) NOSCRIPT No matching script. Please use EVAL.

    Dies zeigt an, dass das Skript mit dem angegebenen SHA1-Hash nicht geladen ist.

  7. 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.