sql >> Base de Datos >  >> NoSQL >> Redis

Transacciones de Redis y secuencias de comandos Lua de ejecución prolongada

Redis ofrece dos mecanismos para manejar transacciones:transacciones basadas en MULTI/EXEC y evaluación de scripts Lua. Redis Lua scripting es el enfoque recomendado y su uso es bastante popular.

Nuestros clientes de Redis™ que tienen secuencias de comandos Lua implementadas a menudo informan este error:“OCUPADO Redis está ocupado ejecutando una secuencia de comandos. Solo puede llamar SCRIPT KILL o SHUTDOWN NOSAVE ”. En esta publicación, explicaremos la propiedad transaccional de los scripts de Redis, de qué se trata este error y por qué debemos tener mucho cuidado al respecto en los sistemas administrados por Sentinel que pueden fallar.

Naturaleza transaccional de los scripts Redis Lua

Las "transacciones" de Redis no son realmente transacciones tal como se entienden convencionalmente; en caso de errores, no se revierten las escrituras realizadas por el script.

La “atomicidad” de los scripts de Redis se garantiza de la siguiente manera:

  • Una vez que una secuencia de comandos comienza a ejecutarse, todos los demás comandos/secuencias de comandos se bloquean hasta que se completa la secuencia de comandos. Entonces, otros clientes ven los cambios realizados por el script o no. Esto se debe a que solo pueden ejecutarse antes o después del script.
  • Sin embargo, Redis no realiza reversiones, por lo que si se produce un error dentro de una secuencia de comandos, se conservarán todos los cambios realizados por la secuencia de comandos y los comandos/secuencias de comandos futuros verán esos cambios parciales.
  • Dado que todos los demás clientes están bloqueados mientras se ejecuta el script, es fundamental que el script se comporte bien y finalice a tiempo.

El valor 'lua-time-limit'

Se recomienda enfáticamente que el script se complete dentro de un límite de tiempo. Redis hace cumplir esto de una manera débil con el valor 'lua-time-limit'. Este es el tiempo máximo permitido (en ms) que el script puede ejecutar. El valor predeterminado es 5 segundos. Este es un tiempo realmente largo para la actividad ligada a la CPU (los scripts tienen acceso limitado y no pueden ejecutar comandos que accedan al disco).

Sin embargo, la secuencia de comandos no se cancela cuando se ejecuta más allá de este tiempo. Redis comienza a aceptar comandos del cliente nuevamente, pero responde con un error OCUPADO.

Si debe eliminar el script en este punto, hay dos opciones disponibles:

  • MATAR CON GUIÓN El comando se puede usar para detener una secuencia de comandos que aún no ha realizado ninguna escritura.
  • Si la secuencia de comandos ya ha realizado escrituras en el servidor y aún debe eliminarse, use SHUTDOWN NOSAVE para apagar el servidor por completo.

Por lo general, es mejor esperar a que el script complete su operación. La información completa sobre los métodos para eliminar la ejecución del script y el comportamiento relacionado está disponible en la documentación.

Transacciones Redis y secuencias de comandos Lua de ejecución prolongadaHaga clic para twittear

Comportamiento en sistemas de alta disponibilidad supervisados ​​por Sentinel

Los sistemas de alta disponibilidad administrados por Sentinel agregan una nueva faceta a esto. De hecho, esta discusión se aplica a cualquier sistema de alta disponibilidad que dependa del sondeo de los servidores de Redis para verificar su estado:

  • Las secuencias de comandos de ejecución prolongada inicialmente bloquearán los comandos del cliente. Más tarde, cuando haya pasado el 'lua-time-limit', el servidor comenzará a responder con errores OCUPADO.
  • Sentinels considerará que dicho nodo no está disponible, y si esto persiste más allá del valor de inactividad después de milisegundos configurado en Sentinels, determinarán que el nodo está inactivo.
  • Si dicho nodo es el maestro, se iniciará una conmutación por error. Un nodo de réplica podría ascender y podría comenzar a aceptar nuevas conexiones de los clientes.
  • Mientras tanto, el maestro anterior finalmente completará la ejecución del script y volverá a estar en línea. Sin embargo, Sentinel eventualmente lo reconfigurará como una réplica y comenzará a sincronizarse con el nuevo maestro. Cualquier dato escrito por el script se perderá.

Consejo de experto

Para lograr una alta disponibilidad (HA), debe implementar una configuración maestro-esclavo. Obtenga información sobre cómo conectarse a servidores Redis en una configuración HA a través de un único punto final.

Demostración

Configuramos un sistema sensible de alta disponibilidad para demostrar este comportamiento de conmutación por error. La configuración tiene 2 servidores Redis ejecutándose en una configuración maestra/réplica que está siendo monitoreada por un quórum de 3 centinelas.

El valor de lua-time-limit se estableció en 500 ms para que comience a responder a los clientes con errores si una secuencia de comandos se ejecuta durante más de 500 ms. El valor de inactividad tras milisegundos en los Sentinels se establece en 5 segundos, de modo que un nodo que informa errores se marca como INACTIVO después de 5 segundos.

Ejecutamos el siguiente script Lua en el maestro:

local i = 0
while (true)
do
local key = "Key-" .. i
local value = "Value-" .. i
redis.call('set', key, value)
i = i + 1
redis.call('time')
end

Esto sigue escribiendo entradas en el maestro de Redis. Nos suscribimos a los eventos en uno de los centinelas para observar el comportamiento.

El script se inicia en el maestro:

$ redis-cli -a  --eval test.lua
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.

Aquí hay una secuencia truncada de actividades como se ve en Sentinel:

3) "+vote-for-leader"
4) "9096772621089bb885eaf7304a011d9f46c5689f 1"
1) "pmessage"
2) "*"
3) "+sdown" <<< master marked DOWN
4) "master test 172.31.2.48 6379"
1) "pmessage"
2) "*"
3) "+odown"
4) "master test 172.31.2.48 6379 #quorum 3/2"
1) "pmessage"
2) "*"
3) "-role-change" << role change initiated
4) "slave 172.31.28.197:6379 172.31.28.197 6379 @ test 172.31.2.48 6379 new reported role is master"
1) "pmessage"
2) "*"
3) "+config-update-from"
4) "sentinel 9096772621089bb885eaf7304a011d9f46c5689f 172.31.2.48 26379 @ test 172.31.2.48 6379"
1) "pmessage"
2) "*"
3) "+switch-master"
4) "test 172.31.2.48 6379 172.31.28.197 6379"

Más tarde, cuando el antiguo maestro se pone en línea, se cambia a una réplica:

3) "-role-change"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is master"
1) "pmessage"
2) "*"
3) "-sdown"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379"
1) "pmessage"
2) "*"
3) "+role-change"
4) "slave 172.31.2.48:6379 172.31.2.48 6379 @ test 172.31.28.197 6379 new reported role is slave"

Todos los datos escritos en el maestro anterior a través del script se pierden.

Recomendaciones

  • Debe conocer las características de sus secuencias de comandos de ejecución prolongada antes de implementarlas en producción.
  • Si su secuencia de comandos infringe regularmente el límite de tiempo de lua, debe revisar la secuencia de comandos minuciosamente para posibles optimizaciones. También puede dividirlo en partes que se completen en duraciones aceptables.
  • Si debe ejecutar secuencias de comandos que infrinjan el límite de tiempo de lua, considere programar estas secuencias de comandos durante períodos en los que la actividad de otros clientes sea baja.
  • También se puede aumentar el valor de lua-time-limit. Esta sería una solución aceptable si otras aplicaciones cliente que se ejecutan en paralelo con el script pueden tolerar recibir respuestas extremadamente retrasadas en lugar de un error OCUPADO y volver a intentarlo más tarde.

Consideraciones adicionales sobre los sistemas de alta disponibilidad supervisados ​​por Sentinel:

  • Si los scripts solo realizan operaciones de lectura y tiene réplicas disponibles, puede mover estos scripts a las réplicas.

Cambie el parámetro Sentinel hacia abajo después de milisegundos a un valor que asegure que no se inicien las conmutaciones por error. Debe hacer esto solo después de una cuidadosa consideración porque aumentar el valor drásticamente comprometerá las características de alta disponibilidad de su sistema. Esto también podría causar que se ignoren las fallas genuinas del servidor.

Más consejos para ti

Conozca la base de datos de Redis:iteración de claves

La capacidad de iterar de forma económica sobre el espacio de claves de Redis es muy importante para familiarizarse con el contenido de la base de datos. Conozca las diversas opciones de iteración de espacios clave disponibles en Redis. Más información

Principales casos de uso de Redis por tipo de estructura de datos principal

Redis puede actuar como una base de datos, un caché o un intermediario de mensajes y no almacena datos en esquemas de bases de datos bien definidos que constituyen tablas, filas y columnas. En cambio, Redis almacena datos en estructuras de datos, lo que lo hace muy flexible de usar. Más información

Seis métricas de supervisión cruciales de Redis que debe vigilar

¿Cómo se asegura de que su implementación de Redis sea correcta y cumpla con sus requisitos? Necesita saber qué métricas de monitoreo observar y una herramienta para monitorear estas métricas críticas del servidor para garantizar su salud. Más información