Integración de Lua en Redis para operaciones atómicas

Implementación de scripts Lua en Redis

Ventajas fundamentales

  • Ejecución atómica: Los scripts Lua se ejecutan de manera indivisible dentro de Redis, eliminando la necesidad de meacnismos transaccionales adicionales.
  • Rendimiento optimizado: Los scripts se almacenan en caché en el servidor tras su carga inicial. Lua, implementado en C, ofrece velocidad de ejecución superior y soporte multiplataforma.
  • Eficiencia de red: Múltiples operaciones pueden combinarse en un solo script, minimizando las comunicaciones de red y el consumo de conexiones.

Comandos esenciales

eval <script_lua> <num_keys> [key ...] [arg ...]
// Ejecuta un script Lua directamente.

script load <script_lua>
// Almacena el script en caché y devuelve su digestión SHA1.

evalsha <sha1> <num_keys> [key ...] [arg ...]
// Ejecuta un script previamente almacenado usando su SHA1.

script exists <sha1>
// Verifica la existencia de un script cacheado (0: no, 1: sí).

script flush
// Elimina todos los scripts almacenados en el servidor.

script kill
// Detiene la ejecución de un script Lua en curso (solo operaciones de lectura).

redis-cli --eval <ruta_script> [key ...] , [arg ...]
// Ejecuta un script Lua desde un archivo externo.

Ejemplos prácticos

Uso directo con EVAL

eval "local ttl = tonumber(ARGV[2])
redis.call('SETEX', KEYS[1], ttl, ARGV[1])
return true" 1 usuario_sesion token_abc123 1800

Caché de scripts con SCRIPT LOAD

script load "local valor = redis.call('GET', KEYS[1])
if not valor then
    redis.call('SET', KEYS[1], ARGV[1])
    return ARGV[1]
end
return valor"

Ejecución mediante SHA1 con EVALSHA

evalsha "b53db15d1c74e222872348f91281a029f6c301e3" 1 clave_configuracion valor_predeterminado

Verificación de existencia

script exists "b53db15d1c74e222872348f91281a029f6c301e3"

Limpieza de caché

script flush

Terminación de scripts

# Script con operación de lectura consumidora de tiempo
redis> eval "local i = 0
while i < 1000000 do
    redis.call('GET', KEYS[1])
    i = i + 1
end" 1 datos_temporales

# Detener script de lectura
redis> script kill

Ejecución desde archivo

Para un bloqueo distribuido simple, el siguiente script podría almcaenarse como lock_manager.lua:

-- Implementación de bloqueo distribuido
local lock_key = KEYS[1]
local lock_value = ARGV[1]
local expire_time = tonumber(ARGV[2])

if redis.call('SETNX', lock_key, lock_value) == 1 then
    redis.call('EXPIRE', lock_key, expire_time)
    return 1
else
    local current_value = redis.call('GET', lock_key)
    if current_value == lock_value then
        redis.call('EXPIRE', lock_key, expire_time)
        return 1
    end
    return 0
end

Se ejecutaría mediante:

redis-cli --eval lock_manager.lua lock:recurso_unico , "session_456" 300

Etiquetas: Redis Lua scripts atómicos bloqueo distribuido rendimiento de base de datos

Publicado el 6-29 04:01