Todos los productos
Search
Centro de documentos

Tair (Redis® OSS-Compatible):Especificaciones de scripts Lua y errores comunes

Última actualización: Sep 03, 2026

Las instancias de Tair (Redis OSS-compatible) admiten comandos Lua. Puede utilizar scripts Lua para gestionar operaciones de comparación e intercambio (CAS) de forma eficiente, mejorar el rendimiento de la instancia e implementar patrones que serían difíciles o ineficientes de lograr por otros medios. Este tema describe la sintaxis básica y las directrices de uso para scripts Lua.

Sintaxis básica

Show details

Para obtener más información sobre los comandos de Redis, visite el sitio web oficial de Redis.

Comando

Sintaxis

Descripción

EVAL

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

Ejecuta un script con los parámetros especificados y devuelve el resultado.

Parámetros:

  • script: El script Lua.

  • numkeys: Un entero no negativo que especifica la cantidad de argumentos de clave en el arreglo KEYS[].

  • KEYS[]: Los argumentos de clave de Redis pasados al script.

  • ARGV[]: Los argumentos pasados al script. Los índices tanto de KEYS[] como de ARGV[] comienzan en 1.

Nota
  • Al igual que el comando SCRIPT LOAD, el comando EVAL almacena el script Lua en la caché de la instancia.

  • El uso inadecuado de KEYS[] y ARGV[] puede provocar comportamientos inesperados, especialmente en modo clúster. Para obtener más información, consulte Special restrictions in cluster architecture.

  • Se recomienda pasar valores en los parámetros KEYS[] y ARGV[] para invocar scripts Lua, en lugar de codificar los parámetros directamente dentro del script. De lo contrario, el uso de memoria de la máquina virtual Lua aumenta y no se puede reducir a la brevedad. En el peor de los casos, se produce un error de falta de memoria (OOM) en la instancia que deriva en pérdida de datos.

EVALSHA

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

Ejecuta un script mediante su resumen SHA1.

Si ejecuta el comando EVALSHA y el script correspondiente al valor sha1 no está en la caché de Redis, este devuelve un error NOSCRIPT. Para resolverlo, utilice el comando EVAL o SCRIPT LOAD para almacenar el script en la caché y vuelva a intentarlo. Para obtener más información, consulte NOSCRIPT error.

SCRIPT LOAD

SCRIPT LOAD script

Almacena el script indicado en la caché de la instancia y devuelve su resumen SHA1.

SCRIPT EXISTS

SCRIPT EXISTS script [script ...]

Comprueba si uno o varios scripts, identificados por sus resúmenes SHA1, existen en la caché de scripts de la instancia. Devuelve 1 por cada script existente y 0 por cada script ausente.

SCRIPT KILL

SCRIPT KILL

Detiene un script Lua en ejecución.

SCRIPT FLUSH

SCRIPT FLUSH

Borra todos los scripts Lua de la caché de scripts de la instancia actual.

A continuación se presentan ejemplos de código para comandos específicos de Redis. Antes de ejecutar los siguientes comandos, ya se ejecutó el comando SET foo value_test.

  • Ejemplo del comando EVAL:

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

    Salida de ejemplo:

    "value_test"
  • Ejemplo del comando SCRIPT LOAD:

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

    Salida de ejemplo:

    "620cd258c2c9c88c9d10db67812ccf663d96bdc6"
  • Ejemplo del comando EVALSHA:

    EVALSHA 620cd258c2c9c88c9d10db67812ccf663d96bdc6 1 foo

    Salida de ejemplo:

    "value_test"
  • Ejemplo del comando SCRIPT EXISTS:

    SCRIPT EXISTS 620cd258c2c9c88c9d10db67812ccf663d96bdc6 ffffffffffffffffffffffffffffffffffffffff

    Salida de ejemplo:

    1) (integer) 1
    2) (integer) 0
  • Ejemplo del comando SCRIPT FLUSH:

    Aviso

    Este comando elimina todos los scripts Lua almacenados en la caché de la instancia. Asegúrese de realizar una copia de seguridad de los scripts Lua antes de ejecutar este comando.

    SCRIPT FLUSH

    Salida de ejemplo:

    OK

Optimización del rendimiento

Optimizar la memoria y la sobrecarga de red

Almacenar en caché una gran cantidad de scripts funcionalmente repetitivos consume mucha memoria e incluso puede desencadenar un error de falta de memoria (OOM). A continuación se muestra un ejemplo de uso incorrecto:

EVAL "return redis.call('set', 'k1', 'v1')" 0
EVAL "return redis.call('set', 'k2', 'v2')" 0

Solución:

  • Para reducir el desperdicio de memoria, evite codificar argumentos como constantes dentro del script Lua.

    # Achieves the same functionality as the incorrect example but only caches the script once.
    EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 k1 v1
    EVAL "return redis.call('set', KEYS[1], ARGV[1])" 1 k2 v2
  • Para mayor eficiencia, se recomienda el siguiente enfoque con el fin de reducir tanto el uso de memoria como la sobrecarga de red.

    SCRIPT LOAD "return redis.call('set', KEYS[1], ARGV[1])"    # After execution, Redis returns "55b22c0d0cedf3866879ce7c854970626dcef0c3".
    EVALSHA 55b22c0d0cedf3866879ce7c854970626dcef0c3 1 k1 v1
    EVALSHA 55b22c0d0cedf3866879ce7c854970626dcef0c3 1 k2 v2

Liberar memoria de scripts Lua

La caché de scripts Lua consume memoria de la instancia, lo cual contribuye a la métrica used_memory. Si el uso de memoria de la instancia se acerca o supera el valor de maxmemory, puede producirse un error de falta de memoria (OOM). A continuación se muestra un ejemplo de error:

-OOM command not allowed when used memory > 'maxmemory'.

Solución:

Ejecute el comando SCRIPT FLUSH desde un cliente para borrar la caché de scripts Lua. El método recomendado depende de la versión de su instancia:

  • Limpieza asíncrona (recomendada): Las versiones de open source Redis 7.0 o posteriores y Tair (Enterprise Edition) 6.0 o posteriores admiten el comando SCRIPT FLUSH ASYNC. Este comando borra la caché de scripts Lua en segundo plano sin bloquear la instancia, lo que minimiza el impacto en sus servicios.

    SCRIPT FLUSH ASYNC
  • Limpieza síncrona: En versiones anteriores, el comando SCRIPT FLUSH funciona de manera síncrona. Si la instancia tiene una gran cantidad de scripts Lua en caché, este comando puede bloquearla durante un periodo prolongado y dejarla no disponible. Utilice este comando con precaución, preferiblemente fuera de las horas pico.

    SCRIPT FLUSH
Nota

Hacer clic en Purge Data en la consola solo borra los datos y no limpia la caché de scripts Lua.

Además, evite escribir scripts Lua excesivamente grandes para prevenir un alto consumo de memoria. No realice escrituras masivas de datos dentro de un script Lua, ya que esto puede causar un aumento repentino en el uso de memoria y derivar en un error OOM. Si su lógica de negocio lo permite, se recomienda habilitar la evicción de datos (habilitada de forma predeterminada con la directiva volatile-lru) para ahorrar espacio en memoria. Sin embargo, la instancia no desaloja la caché de scripts Lua, independientemente de si la evicción de datos está habilitada.

Gestión de errores

Error NOSCRIPT

Cuando utiliza el comando EVALSHA, si el script correspondiente al valor sha1 no está almacenado en la caché de la instancia, esta devuelve un error NOSCRIPT. A continuación se muestra un ejemplo:

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

Solución:

Utilice el comando EVAL o SCRIPT LOAD para almacenar el script en la caché de la instancia y vuelva a intentarlo. No obstante, la instancia no garantiza la persistencia ni la replicación de los scripts Lua. En algunos escenarios, como una migración de instancia o un cambio de configuración, la caché de scripts Lua puede borrarse. Por lo tanto, su aplicación cliente debe ser capaz de gestionar este error. Para obtener más información, consulte Persistence and replication issues.

La siguiente demostración en Python muestra un ejemplo de cómo gestionar un error NOSCRIPT. Esta demostración utiliza un script Lua para realizar una operación de anteposición de cadenas.

Nota

También puede utilizar la biblioteca redis-py para Python con el fin de gestionar este tipo de error. La biblioteca proporciona una clase Script que encapsula la lógica de bajo nivel para la creación de scripts Lua en Redis, como la captura de errores NOSCRIPT.

import redis
import hashlib

# This function takes a Lua script as a string and returns its SHA1 digest.
def calcSha1(strin):
    sha1_obj = hashlib.sha1()
    sha1_obj.update(strin.encode('utf-8'))
    sha1_val = sha1_obj.hexdigest()
    return sha1_val

class MyRedis(redis.Redis):

    def __init__(self, host="localhost", port=6379, password=None, decode_responses=False):
        redis.Redis.__init__(self, host=host, port=port, password=password, decode_responses=decode_responses)

    def prepend_inLua(self, key, value):
        script_content = """\
        local suffix = redis.call("get", KEYS[1])
        local prefix = ARGV[1]
        local new_value = prefix..suffix
        return redis.call("set", KEYS[1], new_value)
        """
        script_sha1 = calcSha1(script_content)
        if self.script_exists(script_sha1)[0]:      # Check if the script is cached in Redis.
            return self.evalsha(script_sha1, 1, key, value) # If cached, run the script with EVALSHA.
        else:
            return self.eval(script_content, 1, key, value) # Otherwise, run the script with EVAL, which also caches it. Alternatively, you could use SCRIPT LOAD and then EVALSHA.

r = MyRedis(host="r-******.redis.rds.aliyuncs.com", password="***:***", port=6379, decode_responses=True)

print(r.prepend_inLua("k", "v"))
print(r.get("k"))
            

Errores de tiempo de espera en scripts Lua

  • Dado que los scripts Lua se ejecutan de forma atómica, un script lento puede bloquear la instancia. Si un script se ejecuta durante más de 5 segundos, la instancia devuelve un error BUSY para todos los demás comandos hasta que finaliza la ejecución del script.

    BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.

    Solución:

    Puede utilizar el comando SCRIPT KILL para finalizar el script Lua o esperar a que se complete.

    Nota
    • El comando SCRIPT KILL no surte efecto durante los primeros 5 segundos de ejecución de un script lento porque la instancia está bloqueada.

    • Al escribir scripts Lua, estime su tiempo de ejecución y compruebe que no existan problemas como bucles infinitos. Esto ayuda a evitar que los scripts de larga duración bloqueen la instancia y dejen el servicio no disponible. Si es necesario, divida los scripts largos en otros más pequeños.

  • Si el script Lua actual ya ejecutó un comando de escritura, el comando SCRIPT KILL no funcionará. A continuación se muestra un ejemplo de error:

    (error) UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.

    Solución:

    En la consola, vaya a la página Instances y haga clic en restart para la instancia correspondiente.

Problemas de persistencia y replicación

La instancia almacena en caché los scripts Lua ejecutados de forma indefinida, a menos que se reinicie o se invoque el comando SCRIPT FLUSH. Sin embargo, en ciertas situaciones, como una migración de instancia, un cambio de configuración, una actualización de versión o un failover de alta disponibilidad (HA), la instancia no garantiza la persistencia de los scripts Lua ni su replicación a otros nodos.

Solución:

Dado que la instancia no garantiza la persistencia ni la replicación de scripts, debe almacenar todos los scripts Lua localmente. Cuando sea necesario, utilice el comando EVAL o SCRIPT LOAD para volver a almacenar los scripts en la caché de la instancia. Esto evita errores NOSCRIPT que pueden ocurrir si la caché de scripts se borra durante operaciones como un reinicio de instancia o un failover de HA.

Restricciones especiales en arquitectura de clúster

Restricciones de la arquitectura de clúster

  • Para garantizar la atomicidad, un script Lua no se puede dividir y debe ejecutarse en un solo shard dentro de una arquitectura de clúster. La instancia suele utilizar una clave para determinar a qué shard enrutar el comando. Por lo tanto, debe especificar como mínimo una clave al ejecutar un script Lua en un clúster. Si un script accede a varias claves, todas deben pertenecer al mismo slot; de lo contrario, el script fallará o devolverá resultados incorrectos. Los comandos sin claves, como KEYS, SCAN y FLUSHDB, pueden ejecutarse, pero solo devolverán datos de un único shard. Estas limitaciones son inherentes a la arquitectura de Redis Cluster.

  • Ejecutar el comando SCRIPT LOAD en un solo nodo no garantiza que el script se almacene en los demás nodos.

Códigos de error en modo proxy

El proxy realiza comprobaciones de sintaxis para identificar proactivamente los casos en los que las claves abarcan varios slots. Esto ayuda a detectar problemas temprano para facilitar la resolución. El método de comprobación del proxy difiere del de la máquina virtual Lua, lo que genera restricciones adicionales al ejecutar comandos Lua en modo proxy. Por ejemplo, el comando UNPACK no es compatible, y los comandos EVAL, EVALSHA y los de la serie SCRIPT no se pueden utilizar dentro de transacciones MULTI/EXEC.

También puede deshabilitar algunas de las comprobaciones de sintaxis Lua del proxy al desactivar el parámetro script_check_enable.

Adicionalmente, para una instancia con división de lectura/escritura, si el parámetro readonly_lua_route_ronode_enable está habilitado, el proxy comprueba si un script Lua contiene únicamente comandos de solo lectura para determinar si se puede reenviar a un nodo de solo lectura. Esta lógica de comprobación impone limitaciones en la sintaxis Lua.

Nota

Deshabilitar el parámetro script_check_enable tiene los siguientes efectos:

  • Para instancias de open source Redis 5.0 (versiones menores anteriores a 5.0.8) o Redis 4.0 y anteriores, no se recomienda deshabilitar este parámetro. Hacerlo puede provocar que un script devuelva un mensaje de éxito incluso cuando se ejecuta incorrectamente.

  • Para otras versiones, deshabilitar este parámetro detiene la comprobación de sintaxis Lua por parte del proxy, pero los nodos de datos seguirán realizando sus comprobaciones de sintaxis normales.

A continuación se detallan los códigos de error específicos y sus causas.

Limitaciones de la arquitectura Redis Cluster

  • Código de error: -ERR for redis cluster, eval/evalsha number of keys can't be negative or zero\r\n

    Descripción: Debe especificar como mínimo una clave al ejecutar un script Lua. El proxy utiliza la clave para determinar a qué shard reenviar el script.

    # Correct example
    EVAL "return redis.call('get', KEYS[1])" 1 fooeval
    
    # Incorrect example
    EVAL "return redis.call('get', 'foo')" 0
  • Código de error: -ERR 'xxx' command keys must in same slot

    Descripción: Todas las claves en un script Lua deben pertenecer al mismo slot.

    # Correct example:
    EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo {foo}bar
    
    # Incorrect example:
    EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo foobar

Restricciones de sintaxis Lua del proxy

Nota

Puede evitar las comprobaciones adicionales de sintaxis Lua del proxy al disabling el parámetro script_check_enable.

  • Código de error: -ERR bad lua script for redis cluster, nested redis.call/redis.pcall

    Descripción: No se admiten llamadas anidadas a Redis. Utilice variables locales como alternativa.

    # Correct example
    EVAL "local value = redis.call('GET', KEYS[1]); redis.call('SET', KEYS[2], value)" 2 foo bar
    
    # Incorrect example
    EVAL "redis.call('SET', KEYS[1], redis.call('GET', KEYS[2]))" 2 foo bar
  • Código de error: -ERR bad lua script for redis cluster, first parameter of redis.call/redis.pcall must be a single literal string

    Descripción: El comando invocado dentro de redis.call/pcall debe ser una cadena literal.

    # Correct example
    eval "redis.call('GET', KEYS[1])" 1 foo
    
    # Incorrect example
    eval "local cmd = 'GET'; redis.call(cmd, KEYS[1])" 1 foo

Restrictions in specific versions (applies only to open source Redis 5.0 with minor versions earlier than 5.0.8, Redis 4.0 and earlier, cloud-native edition with proxy versions earlier than 7.0.2, and classic edition with proxy versions earlier than 6.8.12)

Nota
  • Las siguientes restricciones aplican únicamente a open source Redis 5.0 (versiones menores anteriores a 5.0.8), Redis 4.0 y anteriores, o instancias con versiones de proxy antiguas (cloud-native edition anterior a 7.0.2 o classic edition anterior a 6.8.12).

  • Por lo general, si las versiones de su instancia y proxy son superiores a las listadas, puede ignorar el siguiente contenido. Sin embargo, si su instancia es de una versión superior pero aún presenta estas restricciones, modifique cualquier parámetro del proxy (como query_cache_expire), espere 1 minuto y vuelva a intentarlo.

  • Código de error: -ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array\r\n

    Descripción: Todas las claves deben pasarse a través del arreglo KEYS. Para los comandos dentro de redis.call/pcall, las posiciones de las claves deben usar el arreglo KEYS, y no se puede sustituir KEYS con una variable Lua.

    # Correct example:
    EVAL "return redis.call('mget', KEYS[1], KEYS[2])" 2 foo {foo}bar
    
    # Incorrect examples:
    EVAL "return redis.call('mget', KEYS[1], '{foo}bar')" 1 foo                      # The key '{foo}bar' should be passed through the KEYS array.
    EVAL "local i = 2 return redis.call('mget', KEYS[1], KEYS[i])" 2 foo {foo}bar    # This script is not allowed in proxy mode because the KEYS array index is a variable. This restriction does not exist in direct connection mode.
    EVAL "return redis.call('mget', KEYS[1], ARGV[1])" 1 foo {foo}bar                # An element from the ARGV array should not be used as a key.
  • Código de error: -ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array, include destination, and KEYS should not be in expression

    Descripción: El parámetro destination de los comandos ZUNIONSTORE y ZINTERSTORE debe pasarse mediante el arreglo KEYS.

  • Código de error: -ERR bad lua script for redis cluster, ZUNIONSTORE/ZINTERSTORE numkeys parameter should be a single number and not expression

    Descripción: El parámetro numkeys de los comandos ZUNIONSTORE y ZINTERSTORE debe ser una constante, no una expresión.

  • Código de error: -ERR bad lua script for redis cluster, ZUNIONSTORE/ZINTERSTORE numkeys value is not an integer or out of range

    Descripción: El parámetro numkeys de los comandos ZUNIONSTORE y ZINTERSTORE no es un número.

  • Código de error: -ERR bad lua script for redis cluster, ZUNIONSTORE/ZINTERSTORE all the keys that the script uses should be passed using the KEYS array

    Descripción: Todas las claves para los comandos ZUNIONSTORE y ZINTERSTORE deben pasarse mediante el arreglo KEYS.

  • Código de error: -ERR bad lua script for redis cluster, XREAD/XREADGROUP all the keys that the script uses should be passed using the KEYS array

    Descripción: Todas las claves para los comandos XREAD y XREADGROUP deben pasarse mediante el arreglo KEYS.

  • Código de error: -ERR bad lua script for redis cluster, all the keys that the script uses should be passed using the KEYS array, and KEYS should not be in expression, sort command store key does not meet the requirements

    Descripción: La clave para el comando SORT debe pasarse mediante el arreglo KEYS.

Problemas de permisos de lectura/escritura

  • Código de error: -ERR Write commands are not allowed from read-only scripts

    Descripción: Los scripts Lua enviados con el comando EVAL_RO no pueden contener comandos de escritura.

  • Código de error: -ERR bad write command in no write privilege

    Descripción: Los scripts Lua enviados desde una cuenta de solo lectura no pueden contener comandos de escritura.

Comandos no compatibles

  • Código de error: -ERR script debug not support

    Descripción: Actualmente, el proxy no admite el comando SCRIPT DEBUG.

  • Código de error: -ERR bad lua script for redis cluster, redis.call/pcall unkown redis command xxx

    Descripción: El script Lua contiene un comando que no es compatible con el proxy. Para obtener más información, consulte Command restrictions on cluster and read/write splitting instances.

Errores de sintaxis Lua

  • Código de error: -ERR bad lua script for redis cluster, redis.call/pcall expect '(' o -ERR bad lua script for redis cluster, redis.call/redis.pcall definition is not complete, expect ')'

    Nota: Se trata de un error de sintaxis Lua porque la función redis.call debe ir seguida de un par completo de paréntesis: ( y ).

  • Código de error: -ERR bad lua script for redis cluster, at least 1 input key is needed for ZUNIONSTORE/ZINTERSTORE

    Descripción: El parámetro numkeys de los comandos ZUNIONSTORE y ZINTERSTORE debe ser mayor que 0.

  • Código de error: -ERR bad lua script for redis cluster, ZUNIONSTORE/ZINTERSTORE key count < numkeys

    Descripción: La cantidad real de claves para el comando ZUNIONSTORE o ZINTERSTORE es menor que el valor numkeys especificado.

  • Código de error: -ERR bad lua script for redis cluster, xread/xreadgroup command syntax error

    Descripción: La sintaxis del comando XREAD o XREADGROUP es incorrecta. Compruebe la cantidad de parámetros.

  • Código de error: -ERR bad lua script for redis cluster, xread/xreadgroup command syntax error, streams must be specified

    Descripción: Los comandos XREAD y XREADGROUP deben incluir el parámetro streams.

  • Código de error: -ERR bad lua script for redis cluster, sort command syntax error

    Descripción: La sintaxis del comando SORT es incorrecta.

Preguntas frecuentes

  • P: ¿Puedo ejecutar scripts Lua en Data Management (DMS)?

    R: La consola de Data Management (DMS) actualmente no admite comandos relacionados con Lua. Para utilizar scripts Lua, conéctese a su instancia mediante un cliente o redis-cli.