¿Por qué Redis para hacer cola?
Tengo la impresión de que Redis puede ser un buen candidato para implementar un sistema de colas. Hasta este momento, hemos estado utilizando nuestra base de datos MySQL con sondeo, o RabbitMQ. Con RabbitMQ hemos tenido muchos problemas: las bibliotecas del cliente son muy pobres y tienen errores y nos gustaría no invertir demasiadas horas de desarrollador en solucionarlos, algunos problemas con la consola de administración del servidor, etc. Y, por el momento siendo al menos, no estamos tratando de alcanzar milisegundos o presionando seriamente el rendimiento, por lo que mientras un sistema tenga una arquitectura que soporte una cola de manera inteligente, probablemente estemos en buena forma.
Bien, ese es el trasfondo. Esencialmente tengo un modelo de cola muy clásico y simple: varios productores que producen trabajo y varios consumidores que consumen trabajo, y tanto los productores como los consumidores deben poder escalar de manera inteligente. Resulta que un ingenuo PUBSUB
no funciona, ya que no quiero que todos los suscriptores consuman trabajo, solo quiero que un suscriptor reciba el trabajo. A primera vista, me parece que BRPOPLPUSH
es un diseño inteligente.
¿Podemos usar BRPOPLPUSH?
El diseño básico BRPOPLPUSH
es que tiene una cola de trabajo y una cola de progreso. Cuando un consumidor recibe trabajo, empuja atómicamente el elemento a la cola de progreso, y cuando completa el trabajo, LREM
es él. Esto evita el bloqueo del trabajo si los clientes mueren y hace que el monitoreo sea bastante fácil; por ejemplo, podemos saber si hay un problema que hace que los consumidores tomen mucho tiempo para realizar tareas, además de saber si hay un gran volumen de tareas.
Se asegura
- el trabajo se entrega exactamente a un consumidor
- el trabajo termina en una cola de progreso, por lo que no puede bloquearse si un consumidor
Los inconvenientes
- Me parece bastante extraño que el mejor diseño que he encontrado en realidad no lo use,
PUBSUB
ya que esto parece ser en lo que se enfoca la mayoría de las publicaciones de blog sobre hacer cola en Redis. Entonces siento que me falta algo obvio. La única forma que veo de usarPUBSUB
sin consumir tareas dos veces es simplemente enviar una notificación de que el trabajo ha llegado, que los consumidores pueden sin bloquearRPOPLPUSH
. - Es imposible solicitar más de un elemento de trabajo a la vez, lo que parece ser un problema de rendimiento. No es muy importante para nuestra situación, pero obviamente dice que esta operación no fue diseñada para un alto rendimiento o esta situación
- En resumen: ¿me estoy perdiendo algo estúpido?
También agrego la etiqueta node.js, porque ese es el lenguaje con el que estoy tratando principalmente. Node puede ofrecer algunas simplificaciones en la implementación, dada su naturaleza de subproceso único y no bloqueante, pero además estoy usando la biblioteca de nodo-redis y las soluciones deberían o pueden ser sensibles a sus fortalezas y debilidades también.