Por que precisamos de agentes de mensagens como o RabbitMQ em um banco de dados como o PostgreSQL?

214

Eu sou novo em corretores de mensagens como o RabbitMQ, que podemos usar para criar tarefas / filas de mensagens para um sistema de agendamento como o Aipo .

Agora, aqui está a pergunta:

  • Posso criar uma tabela no PostgreSQL que pode ser anexada com novas tarefas e consumida pelo programa do consumidor, como o Aipo.

  • Por que diabos eu gostaria de configurar uma tecnologia totalmente nova para isso, como o RabbitMQ?

Agora, acredito que a escala não pode ser a resposta, já que nosso banco de dados como o PostgreSQL pode funcionar em um ambiente distribuído.

Pesquisei em quais problemas o banco de dados apresenta para um problema específico e descobri:

  • pesquisa mantém o banco de dados ocupado e com baixo desempenho
  • travamento da mesa -> novamente com baixo desempenho
  • milhões de linhas de tarefas -> novamente, a pesquisa é de baixo desempenho

Agora, como o RabbitMQ ou qualquer outro intermediário de mensagens resolve esses problemas?

Além disso, descobri que o AMQPprotocolo é o que se segue. O que há de bom nisso?

O Redis também pode ser usado como um intermediário de mensagens? Acho mais análogo ao Memcached do que o RabbitMQ.

Por favor, lançar alguma luz sobre isso!

Yugal Jindle
fonte
9
O impacto do bloqueio deve ser bem menor com o PostgreSQL, porque implementa o MVCC, onde os leitores não são bloqueados pelos escritores e vice-versa. A maioria dos artigos que encontrei criticando o uso de bancos de dados como filas de mensagens tem o MySQL em mente.
precisa saber é o seguinte
Um intermediário de mensagens move os dados entre os nós, enquanto um banco de dados mantém os dados em um único local. O fato de você poder acessar dados em um banco de dados a partir de vários nós não é, por si só, uma boa ferramenta para transferir dados rapidamente entre nós.
theMayer
2
"sistema de agendamento como celery" - acabei de aprender algo que será útil no meu design, com a pergunta . Agora, para ler as respostas ...
Mark K Cowan
o uso do produtor e consumidor do intermediário de mensagens é dissociado.
Giorgi dvalishvili
Você pode ver o link abaixo. Ele tem uma descrição ampla: stackoverflow.com/a/51377756/3073945
Md. Sajedul Karim

Respostas:

110

As filas do Rabbit residem na memória e, portanto, serão muito mais rápidas do que implementá-las em um banco de dados. Uma (boa) fila de mensagens dedicada também deve fornecer recursos essenciais relacionados ao enfileiramento, como controle de fluxo / otimização e a capacidade de escolher diferentes algoritmos de roteamento, para citar alguns (o coelho fornece esses e muito mais). Dependendo do tamanho do seu projeto, você também pode querer que o componente de passagem de mensagens seja separado do banco de dados, para que, se um componente sofrer uma carga pesada, ele não atrapalhe a operação do outro.

Quanto aos problemas que você mencionou:

  • pesquisas mantendo o banco de dados lento e com baixo desempenho : Usando o Rabbitmq, os produtores podem enviar atualizações aos consumidores, com desempenho muito superior ao das pesquisas. Os dados são simplesmente enviados ao consumidor quando necessário, eliminando a necessidade de verificações desnecessárias.

  • travamento da mesa -> novamente com baixo desempenho: Não há mesa para travar: P

  • milhões de linhas de tarefa -> novamente, a pesquisa é de baixo desempenho: Como mencionado acima, o Rabbitmq operará mais rápido à medida que reside na RAM e fornece controle de fluxo. Se necessário, ele também pode usar o disco para armazenar temporariamente as mensagens se ficar sem memória RAM. Após a versão 2.0, o Rabbit melhorou significativamente seu uso de RAM. Opções de cluster também estão disponíveis.

Em relação ao AMQP, eu diria que um recurso muito interessante é a "troca" e a capacidade de rotear para outras trocas. Isso oferece mais flexibilidade e permite criar uma ampla variedade de tipologias de roteamento elaboradas, que podem ser muito úteis ao dimensionar. Para um bom exemplo, consulte:


(fonte: springsource.com )

e: http://blog.springsource.org/2011/04/01/routing-topologies-for-performance-and-scalability-with-rabbitmq/

Finalmente, no que diz respeito aos redis, sim, ele pode ser usado como um intermediário de mensagens e pode se dar bem. No entanto, o Rabbitmq possui mais recursos de enfileiramento de mensagens do que o redis, já que o rabbitmq foi construído a partir do zero para ser uma fila de mensagens dedicada em nível corporativo com todos os recursos. Redis, por outro lado, foi criado principalmente para ser um armazenamento de valores-chave na memória (embora faça muito mais do que isso agora; é referido como um canivete suíço). Ainda assim, eu li / ouvi muitas pessoas obtendo bons resultados com o Redis para projetos de tamanho menor, mas não ouvi muito sobre isso em aplicativos maiores.

Aqui está um exemplo de redis sendo usado em uma implementação de bate-papo de pesquisa longa: http://eflorenzano.com/blog/2011/02/16/technology-behind-convore/

Jaigus
fonte
2
Eu implementei uma implementação JMS (ou seja, um sistema de transmissão de mensagens) em cima de um banco de dados. Eu posso te dizer que é possível, mas não é divertido e geralmente não compensa. Alguns dos problemas mencionados podem ser contornados, mas aumentam bastante a complexidade. Em suma, concordo: use um sistema MQ dedicado, se precisar. No entanto, para cargas de trabalho baixas, você pode se livrar do banco de dados.
Joachim Sauer
1
Você simplesmente cobriu todas as preocupações / dúvidas. Resposta incrível!
Yugal Jindle
Isso é interessante. E a consistência, a propósito? E se houver centenas de trabalhos em uma fila e o nó que os mantém em memória RAM falha?
Mahn
22
Na verdade, com o PostgreSQL, não há pesquisa (consulte NOTIFY) nem bloqueios de tabela (consulte MVCC). Embora o PostgreSQL ainda não tenha sido projetado para enfileiramento de mensagens, ele não é completamente inadequado.
Jkj 29/10/12
3
Como o que o @jkj disse, não há NOTIFY e não há bloqueios de tabelas. O único problema parece ser a alta largura de banda das mensagens. Você não poderia ter uma instância dedicada do PostgreSQL em vez de manter um sistema totalmente novo como o Rabbit? Você pode 1) usar uma única instância do PostgreSQL até atingir um gargalo, depois 2) usar um Postgres dedicado e, finalmente, 3) mudar facilmente para o Rabbit como seu broker. Parece que começar com Rabbit está pré-otimizando.
Joe
71

PostgreSQL 9.5

O PostgreSQL 9.5 é incorporado SELECT ... FOR UPDATE ... SKIP LOCKED. Isso torna a implementação de sistemas de filas de trabalho muito mais simples e fácil. Você pode não precisar mais de um sistema de enfileiramento externo, já que agora é simples buscar linhas que nenhuma outra sessão bloqueou e mantê-las bloqueadas até que você confirme a confirmação de que o trabalho foi concluído. Funciona até com transações de duas fases para quando é necessária coordenação externa.

Os sistemas de enfileiramento externo permanecem úteis, fornecendo funcionalidade enlatada, desempenho comprovado, integração com outros sistemas, opções para dimensionamento horizontal e federação, etc. No entanto, para casos simples, você realmente não precisa mais deles.

versões mais antigas

Você não precisa dessas ferramentas, mas usá-las pode facilitar a vida. Fazer filas no banco de dados parece fácil, mas você descobrirá na prática que o enfileiramento simultâneo confiável e de alto desempenho é realmente difícil de fazer em um banco de dados relacional.

É por isso que existem ferramentas como o PGQ .

Você pode se livrar da pesquisa no PostgreSQL usando LISTEN e NOTIFY, mas isso não resolverá o problema de distribuir com segurança entradas da parte superior da fila para exatamente um consumidor, preservando uma operação altamente simultânea e não bloqueando inserções. Todas as soluções simples e óbvias que você acha que resolverão esse problema realmente não acontecem no mundo real e tendem a se degenerar em versões menos eficientes da busca de filas de trabalhador único.

Se você não precisar de buscas altamente simultâneas de filas para vários trabalhadores, usar uma única tabela de filas no PostgreSQL é totalmente razoável.

Craig Ringer
fonte
11
a linha reliably handing out entries off the top of the queue to exactly one consumer while preserving highly concurrent operation and not blocking inserts. resume - Certo?
Yugal Jindle