Todos los productos
Search
Centro de documentos

PolarDB:Lua script usage guide

Última actualización: Sep 07, 2026

Orca, el protocolo compatible con Redis en PolarDB for MySQL, admite scripts de Lua para ejecutar varios comandos de forma atómica en una sola interacción con la base de datos. Utilice scripts de Lua para implementar bloqueos distribuidos, limitadores de velocidad y actualizaciones condicionales. Así evitará la latencia y los riesgos de condiciones de carrera que generan los múltiples viajes de ida y vuelta.

Requisitos previos

Antes de empezar, asegúrese de contar con lo siguiente:

  • Un clúster de PolarDB que ejecute MySQL 8.0.2 con la versión secundaria del motor 8.0.2.2.33 o posterior.

  • Un endpoint de ORCA configurado con Read/Write establecido en Read/Write (Automatic Read/Write Splitting).

Conceptos clave

Atomicidad: todos los comandos de un script de Lua se ejecutan como una unidad única e indivisible. Ningún otro comando o script puede interrumpir la ejecución, lo cual evita escrituras parciales y estados intermedios.

Caché de scripts: cargue un script una sola vez con SCRIPT LOAD para obtener su suma de comprobación SHA1. Después, invoque ese script de forma repetida con EVALSHA usando únicamente el valor corto de SHA1. Esto reduce el tráfico de red en comparación con enviar el script completo en cada llamada.

Volatilidad de la caché de scripts: la caché de scripts no es persistente. Se borra después de reiniciar el clúster, tras un cambio por alta disponibilidad (HA) o al invocar de manera explícita SCRIPT FLUSH. Diseñe su aplicación para capturar los errores NOSCRIPT y recargar los scripts automáticamente.

Comandos

Todos los comandos de scripting de Lua siguen la misma convención de parámetros: pase los nombres de las claves mediante KEYS[] y los demás argumentos mediante ARGV[]. Los índices de los arreglos comienzan en 1.

Para consultar la especificación completa de Redis, consulte Scripting with Lua y EVAL command reference en redis.io.

Comando

Sintaxis

Descripción

EVAL

EVAL script numkeys [key [key ...]] [arg [arg ...]]

Ejecuta un script de Lua directamente. numkeys es un entero no negativo que indica cuántos argumentos KEYS[] le siguen.

EVAL_RO

EVAL_RO script numkeys [key [key ...]] [arg [arg ...]]

Ejecuta un script de Lua en modo de solo lectura. Devuelve un error si el script contiene comandos de escritura. Úselo en escenarios de división de lectura y escritura.

EVALSHA

EVALSHA sha1 numkeys [key [key ...]] [arg [arg ...]]

Ejecuta un script almacenado en la caché mediante su suma de comprobación SHA1. Devuelve un error NOSCRIPT si el script no está en la caché; vuelva a cargarlo con EVAL o SCRIPT LOAD y reintente.

EVALSHA_RO

EVALSHA_RO sha1 numkeys [key [key ...]] [arg [arg ...]]

Ejecuta un script almacenado en la caché en modo de solo lectura. Tiene el mismo comportamiento que EVALSHA con la restricción de escritura de EVAL_RO.

SCRIPT LOAD

SCRIPT LOAD script

Carga un script en la caché y devuelve su suma de comprobación SHA1. Use esta suma con EVALSHA en las llamadas posteriores.

SCRIPT EXISTS

SCRIPT EXISTS sha1 [sha1 ...]

Comprueba si los scripts están en la caché. Devuelve 1 por cada script almacenado y 0 por cada script ausente.

SCRIPT KILL

SCRIPT KILL

Finaliza el script que se está ejecutando en ese momento. Orca revierte automáticamente cualquier cambio de datos que haya hecho el script, incluidos los scripts de escritura.

SCRIPT FLUSH

`SCRIPT FLUSH [ASYNC \

SYNC]`

Elimina todos los scripts de Lua almacenados en la caché del clúster. SYNC (predeterminado) bloquea la operación hasta completarla; ASYNC borra la caché en segundo plano.

Comandos no admitidos

A continuación se muestran los comandos que no se pueden invocar dentro de un script de Lua mediante redis.call() ni redis.pcall():

  • Control de transacciones: WATCH, UNWATCH, MULTI, EXEC, DISCARD

  • Comandos de bloqueo: BLPOP, BRPOP

  • Comandos de scripting de Lua: EVAL, EVAL_RO, EVALSHA, EVALSHA_RO, SCRIPT

  • Comandos Pub/Sub: SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE

  • Gestión de conexiones: AUTH, HELLO, CLIENT

Si invoca cualquiera de estos comandos, se devolverá un error de inmediato.

Inicio rápido

Los siguientes ejemplos usan la clave de prueba establecida con SET polardb orca.

EVAL

EVAL: ejecuta un script directamente.

EVAL "return redis.call('GET', KEYS[1])" 1 polardb

Salida:

"orca"

SCRIPT LOAD

SCRIPT LOAD: almacena un script en la caché y obtiene su suma de comprobación SHA1.

SCRIPT LOAD "return redis.call('GET', KEYS[1])"

Salida:

"d3c21d0c2b9ca22f82737626a27bcaf5d288f99f"

EVALSHA

EVALSHA: ejecuta el script almacenado en la caché mediante su suma de comprobación SHA1.

EVALSHA d3c21d0c2b9ca22f82737626a27bcaf5d288f99f 1 polardb

Salida:

"orca"

SCRIPT EXISTS

SCRIPT EXISTS: comprueba si los scripts están en la caché (el primer SHA1 existe, el segundo no).

SCRIPT EXISTS d3c21d0c2b9ca22f82737626a27bcaf5d288f99f ffffffffffffffffffffffffffffffffffffffff

Salida:

1) (integer) 1
2) (integer) 0

Escenarios comunes

Implementar un contador atómico

Utilice scripts de Lua para evitar las condiciones de carrera que generan las operaciones INCR simultáneas. El patrón SCRIPT LOAD + EVALSHA evita transmitir el contenido del script en las llamadas posteriores. De este modo, se reduce el tráfico de red y mejora el rendimiento.

1. Escriba el script y guárdelo de forma local:

-- counter.lua
-- Initialize the key to 0 if it does not exist, then increment by 1.
if redis.call('EXISTS', KEYS[1]) == 0 then
  redis.call('SET', KEYS[1], 0)
end
return redis.call('INCR', KEYS[1])

2. Cargue el script para obtener su suma de comprobación SHA1:

SCRIPT LOAD "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('SET', KEYS[1], 0) end return redis.call('INCR', KEYS[1])"

Salida:

"b547eabbcde73b25330442e4f4e4dc1783b91241"

3. Ejecute el script mediante su suma de comprobación SHA1:

EVALSHA b547eabbcde73b25330442e4f4e4dc1783b91241 1 my_counter

Salida en la primera llamada:

(integer) 1

Salida en la segunda llamada:

(integer) 2

Ejecutar un script de solo lectura

Use EVAL_RO o EVALSHA_RO para garantizar que un script no ejecute operaciones de escritura. Esta opción resulta útil en escenarios de división de lectura y escritura donde los scripts solo deben acceder a las réplicas de lectura.

Antes de usar EVAL_RO, confirme que su script no invoque comandos de escritura como SET, DEL, HSET o LPUSH. Si los incluye, use EVAL en su lugar.

EVAL_RO "return {redis.call('GET', KEYS[1]), redis.call('TTL', KEYS[1])}" 1 polardb

Salida:

1) "orca"
2) (integer) -1
Nota

Si el script contiene comandos de escritura, EVAL_RO devuelve (error) ERR Write commands are not allowed from read-only scripts.

Detener un script de ejecución prolongada

Si un script tarda más de lo esperado y bloquea el clúster, finalícelo con SCRIPT KILL. Orca revierte automáticamente todos los cambios que haya hecho el script.

SCRIPT KILL

Salida:

OK
Nota

SCRIPT KILL solo finaliza el script que se está ejecutando en ese momento. No es posible seleccionar un script específico mediante su SHA1.

Mejores prácticas

Usar SCRIPT LOAD + EVALSHA en cargas de trabajo de producción

Todos los ejemplos siguientes usan SCRIPT LOAD durante el inicio para almacenar los scripts en la caché y luego emplean EVALSHA en cada llamada posterior. Este patrón evita retransmitir el script completo en cada solicitud.

1. Cargue el script durante la inicialización de la aplicación:

# Cache a script that sets a key's value
SCRIPT LOAD "return redis.call('set', KEYS[1], ARGV[1])"

Salida:

"55b22c0d0cedf3866879ce7c854970626dcef0c3"

Almacene este valor SHA1 en su aplicación.

2. Ejecute el script mediante el SHA1 almacenado en la caché:

# Set k1 = v1
EVALSHA 55b22c0d0cedf3866879ce7c854970626dcef0c3 1 k1 v1

# Set k2 = v2 using the same cached script
EVALSHA 55b22c0d0cedf3866879ce7c854970626dcef0c3 1 k2 v2

3. Gestione los errores NOSCRIPT:

Si EVALSHA devuelve un error NOSCRIPT, significa que el script ya no está en la caché. Cambie a EVAL o SCRIPT LOAD para volver a ejecutar el script y almacenarlo de nuevo en la caché. Después, retome el uso de EVALSHA.

Parametrizar scripts con KEYS[] y ARGV[]

Pase todos los datos variables mediante KEYS[] y ARGV[] en lugar de codificar valores de forma fija en el cuerpo del script. Los scripts con valores fijos son cadenas únicas, por lo que cada variante genera una entrada de caché independiente. Esto aumenta el consumo de memoria y anula las ventajas de la caché.

El siguiente ejemplo muestra el antipatrón y el enfoque correcto:

-- Anti-pattern: each hard-coded variant creates a separate cache entry
EVAL "return 'Hello'" 0
EVAL "return 'Scripting!'" 0

-- Correct: one parameterized script reuses the same cache entry for any value
EVAL "return ARGV[1]" 0 Hello
EVAL "return ARGV[1]" 0 Scripting!

Mantener los scripts cortos y rápidos

Los scripts de Lua se ejecutan de forma atómica y bloquean todos los demás comandos durante su ejecución. Los scripts de ejecución prolongada o con lotes grandes aumentan la latencia del clúster para el resto de los clientes.

  • Evite bucles complejos o recorridos de datos a gran escala dentro de los scripts.

  • El tiempo de espera de ejecución predeterminado es de 300 segundos. Si un script supera este límite, simplifique la lógica.

  • Divida las operaciones complejas en varios scripts pequeños en lugar de usar uno solo de gran tamaño.

Borrar la caché de scripts de forma segura

Use SCRIPT FLUSH para eliminar todos los scripts almacenados en la caché. Después de borrarla, cualquier llamada a EVALSHA o EVALSHA_RO devolverá un error NOSCRIPT hasta que se vuelvan a cargar los scripts.

Aviso

En clústeres con muchos scripts en la caché, SCRIPT FLUSH puede bloquear el clúster durante un periodo prolongado. Ejecute este comando fuera del horario de mayor demanda.

SCRIPT FLUSH

Salida:

OK

Conserve el código fuente de los scripts en su aplicación e implemente una recuperación automática para los errores NOSCRIPT. Cuando ocurra un error, vuelva a cargar el script con SCRIPT LOAD o regístrelo de nuevo con EVAL.

Preguntas frecuentes

¿Cómo soluciono NOSCRIPT No matching script. Please use EVAL.?

El script ya no está en la caché del clúster. Esto ocurre después de reiniciar el clúster, tras un cambio por HA o al invocar SCRIPT FLUSH. En su cliente, capture los errores NOSCRIPT y recurra a EVAL o SCRIPT LOAD para registrar el script nuevamente. Una vez registrado de nuevo, las llamadas a EVALSHA funcionarán con normalidad.

¿Qué debo hacer cuando un script agota el tiempo de espera?

El tiempo de espera predeterminado es de 300 segundos. Un agotamiento de tiempo suele indicar que la lógica del script es demasiado compleja o que procesa demasiados datos. Para recuperarse, ejecute SCRIPT KILL; PolarDB revertirá todos los cambios que haya hecho el script. Para evitar que se repita, optimice el script y evite bucles ineficientes o lecturas de datos a gran escala. También puede dividir la lógica en varios scripts más pequeños.

¿Por qué EVAL_RO devuelve ERR Write commands are not allowed from read-only scripts.?

EVAL_RO y EVALSHA_RO prohíben todas las operaciones de escritura. Revise el script para buscar comandos de escritura como SET, HSET o DEL y elimínelos. Si el script necesita escribir datos, use EVAL o EVALSHA en su lugar.