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.
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:
- El script Lua en sí, como una cadena (string).
- 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.
Abra su terminal y conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (
redis-cli).redis-cliAhora, ejecutemos un script Lua usando
EVAL. Este script incrementará un contador llamadomycountery devolverá el valor incrementado.EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounterAnalicemos este comando:
EVAL "local current = redis.call('INCR', KEYS[1]); return current": Este es el script Lua en sí. Utilizaredis.call('INCR', KEYS[1])para incrementar el valor de la clave especificada enKEYS[1]. El arrayKEYScontiene 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) 1Si ejecuta el mismo comando nuevamente, verá el incremento del contador:
EVAL "local current = redis.call('INCR', KEYS[1]); return current" 1 mycounterSalida (Output):
(integer) 2Verifiquemos el valor de la clave
mycounterutilizando el comandoGET:GET mycounterSalida (Output):
"2"Como puede ver, el script Lua incrementó el contador con éxito.
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 myvalueEn 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 claveKEYS[1]existe. Si no existe, establece la clave al valorARGV[1]y devuelve1. De lo contrario, devuelve0.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) 1Esto indica que la clave
mykeyse estableció enmyvalue.Comprobemos el valor de
mykey:GET mykeySalida (Output):
"myvalue"Si ejecuta el comando
EVALnuevamente:EVAL "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], ARGV[1]); return 1 else return 0 end" 1 mykey myvalueSalida (Output):
(integer) 0Esta vez, el script devolvió
0porque la clave ya existía.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:
- El script Lua en sí, como una cadena (string).
- El número de claves a las que accederá el script.
- Los nombres de las claves.
- 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.
Conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (
redis-cli).redis-cliAhora, ejecutemos un script Lua usando
EVALque incrementa un contador por una cantidad especificada.EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current" 1 mycounter 5Analicemos este comando:
EVAL "local current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current": Este es el script Lua. Utilizaredis.call('INCRBY', KEYS[1], ARGV[1])para incrementar el valor de la clave especificada enKEYS[1]por la cantidad especificada enARGV[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á comoARGV[1].
Debería ver una salida similar a esta (asumiendo que
mycounterestaba en 2 desde el paso anterior):(integer) 7El script incrementó la clave
mycounteren 5.Verifiquemos el valor de la clave
mycounterutilizando el comandoGET:GET mycounterSalida (Output):
"7"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 mynewvalueEn este comando:
EVAL "redis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]": Este es el script Lua. Establece la claveKEYS[1]al valorARGV[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"Comprobemos el valor de
mynewkey:GET mynewkeySalida (Output):
"mynewvalue"El script estableció correctamente la clave
mynewkeyal valormynewvalue.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 worldEn este comando:
EVAL "local result = ARGV[1] .. ARGV[2]; redis.call('SET', KEYS[1], result); return result": Este es el script Lua. ConcatenaARGV[1]yARGV[2]usando el operador.., establece la claveKEYS[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"Comprobemos el valor de
combinedkey:GET combinedkeySalida (Output):
"helloworld"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.
Conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (
redis-cli).redis-cliAhora, 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.
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.
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.
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 6b1e8dd2999cb08546e74339c0c9489f9f89a84bSalida (Output):
1) (integer) 1Esto indica que el script está cargado.
Si intenta verificar un script que no está cargado:
SCRIPT EXISTS 0000000000000000000000000000000000000000Salida (Output):
1) (integer) 0Esto indica que el script no está cargado.
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:
- El hash SHA1 del script cargado.
- El número de claves (keys) a las que accederá el script.
- Los nombres de las claves.
- 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.
Conéctese al servidor Redis utilizando la interfaz de línea de comandos de Redis (
redis-cli).redis-cliAhora, 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 scriptlocal current = redis.call('INCRBY', KEYS[1], ARGV[1]); return current? Si no, deberá cargar el script nuevamente usandoSCRIPT LOAD. Para este ejemplo, asumiremos que el hash es6b1e8dd2999cb08546e74339c0c9489f9f89a84b.EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b 1 mycounter 5Analicemos este comando:
EVALSHA 6b1e8dd2999cb08546e74339c0c9489f9f89a84b: Esto especifica que queremos ejecutar el script con el hash SHA16b1e8dd2999cb08546e74339c0c9489f9f89a84b.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á comoARGV[1].
Debería ver una salida similar a esta (asumiendo que
mycounterestaba en 7 desde el paso anterior):(integer) 12El script incrementó la clave
mycounteren 5.Verifiquemos el valor de la clave
mycounterutilizando el comandoGET:GET mycounterSalida (Output):
"12"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 scriptredis.call('SET', KEYS[1], ARGV[1]); return ARGV[1]? Si no, deberá cargar el script nuevamente usandoSCRIPT LOAD. Para este ejemplo, asumiremos que el hash esa8b2b3648969459a8198262a9166e945e890987c.EVALSHA a8b2b3648969459a8198262a9166e945e890987c 1 anotherkey anothervalueDebería ver una salida similar a esta:
"anothervalue"Comprobemos el valor de
anotherkey:GET anotherkeySalida (Output):
"anothervalue"Si intenta ejecutar un script con un hash SHA1 inválido, obtendrá un error:
EVALSHA 0000000000000000000000000000000000000000 1 mykey myvalueSalida (Output):
(error) NOSCRIPT No matching script. Please use EVAL.Esto indica que el script con el hash SHA1 especificado no está cargado.
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.


