Por que Redis para filas?
Tenho a impressão de que o Redis pode ser um bom candidato para a implementação de um sistema de filas. Até este momento, usamos nosso banco de dados MySQL com polling, ou RabbitMQ. Com o RabbitMQ, tivemos muitos problemas - as bibliotecas clientes são muito ruins e com erros e gostaríamos de não investir muitas horas de desenvolvedor para corrigi-las, alguns problemas com o console de gerenciamento de servidores etc. E, por enquanto sendo, pelo menos, não estamos buscando milissegundos ou pressionando seriamente o desempenho, desde que um sistema tenha uma arquitetura que ofereça suporte a uma fila de maneira inteligente, provavelmente estamos em boa forma.
Ok, então esse é o plano de fundo. Essencialmente, eu tenho um modelo de fila simples e muito clássico - vários produtores produzindo trabalho e vários consumidores consumindo trabalho, e tanto produtores quanto consumidores precisam ser capazes de escalar de maneira inteligente. Acontece que um ingênuo PUBSUB
não funciona, já que não quero que todos os assinantes consumam trabalho, só quero que um assinante receba o trabalho. Na primeira passagem, parece-me BRPOPLPUSH
um design inteligente.
Podemos usar o BRPOPLPUSH?
O design básico BRPOPLPUSH
é que você tem uma fila de trabalho e uma fila de progresso. Quando um consumidor recebe trabalho, ele empurra atomicamente o item para a fila de progresso e, quando conclui o trabalho, LREM
é ele. Isso evita a interrupção do trabalho se os clientes morrem e torna o monitoramento bastante fácil - por exemplo, podemos dizer se há um problema que leva os consumidores a demorar muito tempo para executar tarefas, além de saber se há um grande volume de tarefas.
Garante
- o trabalho é entregue a exatamente um consumidor
- o trabalho acaba em uma fila de progresso, por isso não pode ser um buraco negro se um consumidor
As desvantagens
- Parece-me bastante estranho que o melhor design que eu encontrei não seja realmente usado,
PUBSUB
pois esse parece ser o foco da maioria das postagens de blogs sobre filas no Redis. Então, sinto que estou perdendo algo óbvio. A única maneira que eu vejo usandoPUBSUB
sem consumir tarefas duas vezes é simplesmente enviar uma notificação de que o trabalho chegou, o que os consumidores podem então não bloquearRPOPLPUSH
. - É impossível solicitar mais de um item de trabalho por vez, o que parece ser um problema de desempenho. Não é enorme para a nossa situação, mas obviamente diz que esta operação não foi projetada para alto rendimento ou para esta situação
- Em resumo: estou perdendo alguma coisa estúpida?
Também adicionando a tag node.js, porque esse é o idioma com o qual estou lidando principalmente. O nó pode oferecer algumas simplificações na implementação, dada a natureza de thread único e não bloqueador, mas além disso, estou usando a biblioteca e as soluções node-redis e devem ou podem ser sensíveis a seus pontos fortes e fracos.