Scripting Lua en Redis

RedisRedisBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, explorará Redis Lua Scripting, centrándose en la ejecución de scripts Lua directamente dentro de Redis para realizar operaciones complejas de manera eficiente. Este laboratorio cubre el uso del comando EVAL para ejecutar scripts, pasar argumentos a los scripts, cargar scripts con SCRIPT LOAD y ejecutar scripts cargados con EVALSHA.

Comenzaremos ejecutando un script Lua simple que incrementa un contador de Redis usando EVAL, demostrando cómo especificar el script, el número de claves (keys) a las que accede y los nombres de las claves. Luego, aprenderemos cómo cargar scripts en Redis y ejecutarlos usando su hash SHA1, mejorando el rendimiento al evitar la transmisión repetida de scripts.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL redis(("Redis")) -.-> redis/RedisGroup(["Redis"]) redis/RedisGroup -.-> redis/access_cli("Connect Using CLI") redis/RedisGroup -.-> redis/store_string("Set String Value") redis/RedisGroup -.-> redis/fetch_string("Get String Value") redis/RedisGroup -.-> redis/increment_int("Increase Integer Value") subgraph Lab Skills redis/access_cli -.-> lab-552099{{"Scripting Lua en Redis"}} redis/store_string -.-> lab-552099{{"Scripting Lua en Redis"}} redis/fetch_string -.-> lab-552099{{"Scripting Lua en Redis"}} redis/increment_int -.-> lab-552099{{"Scripting Lua en Redis"}} end

Ejecutar Script Lua con EVAL

En este paso, exploraremos cómo ejecutar scripts Lua directamente dentro de Redis utilizando el comando EVAL. Esto le permite realizar operaciones complejas en sus datos en una sola solicitud, reduciendo la latencia de la red y mejorando el rendimiento.

Antes de comenzar, comprendamos los conceptos básicos de EVAL. El comando EVAL toma dos argumentos principales:

  1. El script Lua en sí, como una cadena (string).
  2. El número de claves (keys) a las que accederá el script, seguido de los nombres de las claves reales y cualquier argumento adicional que desee pasar al script.

Aquí hay un ejemplo simple para comenzar. Crearemos un script Lua que incrementa un contador de Redis y devuelve el nuevo valor.

  1. Abra su terminal y conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (redis-cli).

    redis-cli
  2. Ahora, ejecutemos un script Lua usando EVAL. Este script incrementará un contador llamado mycounter y devolverá el valor incrementado.

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

    Analicemos este comando:

    • EVAL "local current = redis.call('INCR', KEYS[1]); return current": Este es el script Lua en sí. Utiliza redis.call('INCR', KEYS[1]) para incrementar el valor de la clave especificada en KEYS[1]. El array KEYS contiene los nombres de las claves pasadas al script. Finalmente, devuelve el valor incrementado.
    • 1: Esto indica que el script accederá a una clave.
    • mycounter: Este es el nombre de la clave a la que accederá el script.

    Debería ver una salida similar a esta:

    (integer) 1

    Si ejecuta el mismo comando nuevamente, verá el incremento del contador:

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

    Salida (Output):

    (integer) 2
  3. Verifiquemos el valor de la clave mycounter utilizando el comando GET:

    GET mycounter

    Salida (Output):

    "2"

    Como puede ver, el script Lua incrementó el contador con éxito.

  4. Ahora, probemos otro ejemplo. Esta vez, crearemos un script que establece una clave a un valor específico si aún no existe.

    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

    En este comando:

    • EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end": Este es el script Lua. Comprueba si la clave KEYS[1] existe. Si no existe, establece la clave al valor ARGV[1] y devuelve 1. De lo contrario, devuelve 0.
    • 1: Esto indica que el script accederá a una clave.
    • mykey: Este es el nombre de la clave.
    • myvalue: Este es el valor a establecer si la clave no existe.

    Debería ver una salida similar a esta:

    (integer) 1

    Esto indica que la clave mykey se estableció en myvalue.

  5. Comprobemos el valor de mykey:

    GET mykey

    Salida (Output):

    "myvalue"

    Si ejecuta el comando EVAL nuevamente:

    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

    Salida (Output):

    (integer) 0

    Esta vez, el script devolvió 0 porque la clave ya existía.

  6. Salga de redis-cli. Esto es importante para que los cambios se registren.

    exit

Pasar Argumentos a un Script con EVAL

En el paso anterior, aprendimos cómo ejecutar scripts Lua con EVAL y acceder a las claves (keys). Ahora, exploremos cómo pasar argumentos a estos scripts. Esto permite scripts más dinámicos y reutilizables.

Recuerde que el comando EVAL toma los siguientes argumentos:

  1. El script Lua en sí, como una cadena (string).
  2. El número de claves a las que accederá el script.
  3. Los nombres de las claves.
  4. Cualquier argumento adicional que desee pasar al script. Se accede a estos argumentos dentro del script Lua utilizando el array ARGV.

Comencemos con un ejemplo. Crearemos un script Lua que agrega un valor a un contador de Redis. La clave del contador y el valor a agregar se pasarán como argumentos.

  1. Conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (redis-cli).

    redis-cli
  2. Ahora, ejecutemos un script Lua usando EVAL que incrementa un contador por una cantidad especificada.

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

    Analicemos este comando:

    • EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current": Este es el script Lua. Utiliza redis.call('INCRBY', KEYS[1], ARGV[1]) para incrementar el valor de la clave especificada en KEYS[1] por la cantidad especificada en ARGV[1].
    • 1: Esto indica que el script accederá a una clave.
    • mycounter: Este es el nombre de la clave a la que accederá el script.
    • 5: Este es el argumento que se pasará al script y al que se accederá como ARGV[1].

    Debería ver una salida similar a esta (asumiendo que mycounter estaba en 2 desde el paso anterior):

    (integer) 7

    El script incrementó la clave mycounter en 5.

  3. Verifiquemos el valor de la clave mycounter utilizando el comando GET:

    GET mycounter

    Salida (Output):

    "7"
  4. Ahora, probemos otro ejemplo con argumentos de cadena (string). Crearemos un script que establece una clave a un valor, donde tanto la clave como el valor se pasan como argumentos.

    EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]" 1 mynewkey mynewvalue

    En este comando:

    • EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]": Este es el script Lua. Establece la clave KEYS[1] al valor ARGV[1] y devuelve el valor.
    • 1: Esto indica que el script accederá a una clave.
    • mynewkey: Este es el nombre de la clave.
    • mynewvalue: Este es el valor a establecer.

    Debería ver una salida similar a esta:

    "mynewvalue"
  5. Comprobemos el valor de mynewkey:

    GET mynewkey

    Salida (Output):

    "mynewvalue"

    El script estableció correctamente la clave mynewkey al valor mynewvalue.

  6. Puede pasar múltiples argumentos al script. Por ejemplo, creemos un script que concatena dos cadenas (strings) pasadas como argumentos y establece el resultado en una clave.

    EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result" 1 combinedkey hello world

    En este comando:

    • EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result": Este es el script Lua. Concatena ARGV[1] y ARGV[2] usando el operador .., establece la clave KEYS[1] al resultado y devuelve el resultado.
    • 1: Esto indica que el script accederá a una clave.
    • combinedkey: Este es el nombre de la clave.
    • hello: Este es el primer argumento de cadena.
    • world: Este es el segundo argumento de cadena.

    Debería ver una salida similar a esta:

    "helloworld"
  7. Comprobemos el valor de combinedkey:

    GET combinedkey

    Salida (Output):

    "helloworld"
  8. Salga de redis-cli. Esto es importante para que los cambios se registren.

    exit

Cargar Script con SCRIPT LOAD

En los pasos anteriores, ejecutamos scripts Lua directamente usando el comando EVAL. Si bien esto es útil para scripts simples, puede volverse engorroso para scripts más grandes y complejos. Redis proporciona el comando SCRIPT LOAD para cargar scripts en la caché de scripts del servidor Redis. Esto le permite ejecutar el script varias veces sin tener que enviar todo el script cada vez, mejorando el rendimiento.

El comando SCRIPT LOAD toma un solo argumento: el script Lua en sí. Devuelve el hash SHA1 del script, que luego puede usar para ejecutar el script usando el comando EVALSHA (que cubriremos en el siguiente paso).

Veamos cómo funciona.

  1. Conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (redis-cli).

    redis-cli
  2. Ahora, carguemos un script Lua usando SCRIPT LOAD. Usaremos el mismo script del paso anterior que incrementa un contador por una cantidad especificada.

    SCRIPT LOAD "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current"

    Este comando cargará el script en la caché de scripts del servidor Redis y devolverá el hash SHA1 del script. Debería ver una salida similar a esta:

    "6b1e8dd2999cb08546e74339c0c9489f9f89a84b"

    Este es el hash SHA1 del script. Tome nota de este hash, ya que lo necesitará en el siguiente paso. El valor exacto del hash puede diferir.

  3. Ahora, carguemos el script que establece una clave (key) a un valor, donde tanto la clave como el valor se pasan como argumentos.

    SCRIPT LOAD "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]"

    Debería ver una salida similar a esta:

    "a8b2b3648969459a8198262a9166e945e890987c"

    Nuevamente, tome nota de este hash.

  4. Carguemos el script que concatena dos cadenas (strings) pasadas como argumentos y establece el resultado en una clave.

    SCRIPT LOAD "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result"

    Debería ver una salida similar a esta:

    "d2a800a974ca96849295220424f9a0664a495345"

    Tome nota de este hash también.

  5. Puede verificar que los scripts estén cargados usando el comando SCRIPT EXISTS. Este comando toma uno o más hashes SHA1 como argumentos y devuelve un array de 0s y 1s, donde 1 indica que el script con el hash correspondiente está cargado y 0 indica que no lo está.

    Por ejemplo, para verificar si el primer script que cargamos todavía está cargado, use el siguiente comando, reemplazando el hash con el que obtuvo en el paso 2:

    SCRIPT EXISTS 6b1e8dd2999cb08546e74339c0c9489f9f89a84b

    Salida (Output):

    1) (integer) 1

    Esto indica que el script está cargado.

    Si intenta verificar un script que no está cargado:

    SCRIPT EXISTS 0000000000000000000000000000000000000000

    Salida (Output):

    1) (integer) 0

    Esto indica que el script no está cargado.

  6. Salga de redis-cli. Esto es importante para que los cambios se registren.

    exit

Ejecutar Script Cargado con EVALSHA

En el paso anterior, aprendimos cómo cargar scripts Lua en la caché de scripts del servidor Redis utilizando el comando SCRIPT LOAD. Ahora, aprenderemos cómo ejecutar esos scripts cargados utilizando el comando EVALSHA.

El comando EVALSHA toma los siguientes argumentos:

  1. El hash SHA1 del script cargado.
  2. El número de claves (keys) a las que accederá el script.
  3. Los nombres de las claves.
  4. Cualquier argumento adicional que desee pasar al script.

Usar EVALSHA es más eficiente que EVAL cuando necesita ejecutar el mismo script varias veces, ya que evita enviar todo el script al servidor cada vez.

Veamos cómo funciona.

  1. Conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (redis-cli).

    redis-cli
  2. Ahora, ejecutemos el script Lua que incrementa un contador por una cantidad especificada usando EVALSHA. ¿Recuerda el hash SHA1 que obtuvo en el paso anterior para el script local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current? Si no, deberá cargar el script nuevamente usando SCRIPT LOAD. Para este ejemplo, asumiremos que el hash es 6b1e8dd2999cb08546e74339c0c9489f9f89a84b.

    EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b 1 mycounter 5

    Analicemos este comando:

    • EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b: Esto especifica que queremos ejecutar el script con el hash SHA1 6b1e8dd2999cb08546e74339c0c9489f9f89a84b.
    • 1: Esto indica que el script accederá a una clave.
    • mycounter: Este es el nombre de la clave a la que accederá el script.
    • 5: Este es el argumento que se pasará al script y al que se accederá como ARGV[1].

    Debería ver una salida similar a esta (asumiendo que mycounter estaba en 7 desde el paso anterior):

    (integer) 12

    El script incrementó la clave mycounter en 5.

  3. Verifiquemos el valor de la clave mycounter utilizando el comando GET:

    GET mycounter

    Salida (Output):

    "12"
  4. Ahora, ejecutemos el script que establece una clave a un valor usando EVALSHA. ¿Recuerda el hash SHA1 que obtuvo en el paso anterior para el script redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]? Si no, deberá cargar el script nuevamente usando SCRIPT LOAD. Para este ejemplo, asumiremos que el hash es a8b2b3648969459a8198262a9166e945e890987c.

    EVALSHA a8b2b3648969459a8198262a9166e945e890987c 1 anotherkey anothervalue

    Debería ver una salida similar a esta:

    "anothervalue"
  5. Comprobemos el valor de anotherkey:

    GET anotherkey

    Salida (Output):

    "anothervalue"
  6. Si intenta ejecutar un script con un hash SHA1 inválido, obtendrá un error:

    EVALSHA 0000000000000000000000000000000000000000 1 mykey myvalue

    Salida (Output):

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

    Esto indica que el script con el hash SHA1 especificado no está cargado.

  7. Salga de redis-cli. Esto es importante para que los cambios se registren.

    exit

Resumen

En este laboratorio, ha explorado el scripting Lua de Redis, centrándose en la ejecución de scripts directamente utilizando el comando EVAL. Aprendimos que EVAL toma el script Lua como una cadena (string), el número de claves (keys) accedidas y los nombres de las claves en sí como argumentos. Practicamos el incremento de un contador de Redis utilizando un script Lua dentro de EVAL, observando cómo el script accedía y modificaba la clave especificada.

Además, aprendimos cómo pasar argumentos a los scripts Lua, cargar scripts en Redis usando SCRIPT LOAD y ejecutar scripts cargados usando EVALSHA. Recuerde salir de redis-cli después de cada paso para asegurarse de que sus comandos se registren correctamente. Esto permite una ejecución más eficiente de scripts complejos.