Quais são as soluções para o problema da fila distribuída?


23

Estou tentando aprender mais sobre as várias maneiras pelas quais o problema de uma fila distribuída pode ser resolvido. Então, eu gostaria de saber quais produtos, serviços, implementações e pesquisas já existem por aí.

Uma implementação enfrentará muitos desafios e será forçada a fazer trocas:

  • Possui pedidos fortes ou frouxos?
  • Possui idempotente?
  • Podemos ter mais filas do que o que pode caber em uma única máquina?
  • Podemos ter mais dados em uma fila do que o que pode caber em uma única máquina?
  • Quantas máquinas podem travar antes de potencialmente perdermos dados?
  • Ele pode tolerar divisões na rede?
  • Ele pode reconciliar dados automaticamente quando uma divisão da rede é corrigida?
  • Pode garantir a entrega quando os clientes podem falhar?
  • Pode garantir que a mesma mensagem não seja entregue mais de uma vez?
  • Um nó pode travar em um determinado ponto, voltar ao normal e não enviar lixo?
  • Você pode adicionar nós ou remover nós de um cluster em execução sem tempo de inatividade?
  • Você pode atualizar nós em um cluster em execução sem tempo de inatividade?
  • Ele pode ser executado sem problemas em servidores heterogêneos?
  • Você pode "enfiar" filas em um grupo de servidores? (exemplo: “essas filas são permitidas apenas no datacenter europeu”)
  • Ele pode garantir a replicação de dados em pelo menos dois datacenters, se disponível?

Não tenho ilusão de que qualquer implementação possa dizer "sim" a tudo isso. Estou apenas interessado em ouvir sobre as várias implementações; como eles funcionam, quais tradeoffs eles fizeram e talvez porque eles decidiram sobre seu conjunto particular de tradeoffs.

Além disso, se houver algum desafio que eu possa ter perdido na lista acima.

Respostas:


13

Escrever um sistema básico de filas é bastante simples, mas, como você observou acima, com todos os desafios, fazer o que é certo é outra questão. Usei sistemas cultivados em casa para os quais escrevi o código-fonte, sistemas de terceiros e vários provedores JMS. O JMS (Java Messaging Service) de longe é a solução mais completa que encontrei até agora. Muito do que você pede está disponível no JMS. Meu provedor JMS favorito é o ActiveMQ. Gratuito, com bom desempenho, fácil de instalar e, mais importante, fácil de incorporar no meu aplicativo com o Spring. Os provedores JMS não fornecem tudo o que você pediu pronto para uso, mas fornecem um conjunto de ferramentas para lidar com muito do que você pediu, caso seu aplicativo precise. Não encontrei muitos aplicativos que precisam de tudo o que você listou. O pedido pode não ser importante (é melhor se não for),

http://activemq.apache.org/what-open-source-integration-solution-works-best-with-activemq-.html

Tem pedidos fortes ou perdidos? Sim. Tem ambos, dependendo das necessidades do seu programa. Aqui estão os detalhes: http://activemq.apache.org/total-ordering.html .

Possui idempotente? Não, mas isso é trivial para implementar em sua camada de aplicativo, caso você precise.

Podemos ter mais filas do que o que pode caber em uma única máquina? Sim. Você pode ter servidores em cluster e, se desejar configurar várias máquinas com filas diferentes, poderá fazê-lo.

Podemos ter mais dados em uma fila do que o que pode caber em uma única máquina? Sim, a maioria dos provedores JMS precisa usar algum tipo de armazenamento persistente / de banco de dados para garantir que as mensagens não sejam descartadas ou perdidas se o provedor JMS cair.

Quantas máquinas podem travar antes de potencialmente perdermos dados? Isso é um pouco mais difícil de responder porque está relacionado ao tempo. No entanto, você pode travar um provedor JMS e, desde que o disco não esteja corrompido, ele voltará e começará onde recebeu a última confirmação. Isso significa que as mensagens podem ser entregues duas vezes, mas se você codificar seu aplicativo para lidar com isso, não será um problema. Contanto que você tenha pelo menos um de cada tipo (produtores, consumidores ou servidores JMS), ele será concluído. Você também pode ter carga / equilíbrio / failover para redundância, se um disco sair com você.

Ele pode agrupar divisões da rede? Acho que entendo o que você quer dizer com "divisão da rede", mas não tenho muita certeza. Eu acho que você quer dizer se os servidores JMS estão em cluster e perdemos a conexão com um dos servidores, ele pula para outro servidor e retoma o local onde parou. Sim, mas, novamente, esses tipos de situações podem levar a mensagens duplicadas, dependendo do momento em que o cliente perdeu a conexão.

Ele pode reconciliar dados automaticamente quando uma divisão da rede é corrigida? Se você estiver usando sessões transacionadas, apenas enviará novamente qualquer mensagem que tenha sido solicitada por um commit para clientes existentes que estão ativos.

Pode garantir a entrega quando os clientes podem falhar? Sim, este é um dos principais objetivos do JMS. Entrega garantida significa que, se uma mensagem estiver na fila, ela será tratada por um cliente.

Pode garantir que a mesma mensagem não seja entregue mais de uma vez? Sim se as sessões transacionadas estiverem sendo usadas. Isso significa que um cliente aceitou a mensagem e chamou commit / rollback. Depois que o commit é chamado, ele não retorna a mensagem.

Um nó pode travar em um determinado ponto, voltar ao normal e não enviar lixo? No caso de você ter filas em cluster duráveis. Sim, ele não emitirá "lixo" se o outro nó no cluster tiver entregue a mensagem. Ainda pode reenviar qualquer coisa que não tenha sido reconhecida.

Você pode adicionar nós ou remover nós de um cluster em execução sem tempo de inatividade? Sim.

Você pode atualizar nós em um cluster em execução sem tempo de inatividade? Isso é um pouco mais complicado para eu responder, mas acredito que sim, você pode fazer isso.

Ele pode ser executado sem problemas em servidores heterogêneos? o que isso significa, exatamente? Descobri que a maioria dos provedores JMS é muito fácil de executar em ambientes que utilizam hardware, sistema operacional, etc. diferentes. Embora, se você quer dizer desempenho, isso é outra coisa. Qualquer sistema de processamento distribuído pode ser impactado negativamente por um nó lento. Eu tinha 2 servidores Intel Core executando a fila e os consumidores. São 16 núcleos juntos e obtive melhor desempenho usando apenas essas duas caixas do que quando adicionei uma máquina de núcleo único como consumidor. Aquela máquina de núcleo único era tão mais lenta que desacelerou a grade inteira por um fator de 2x. Isso não tinha nada a ver com o JMS em si.

Você pode "enfiar" filas em um grupo de servidores? Resposta curta sim. Posso pensar em uma maneira de executar um cluster apenas no data center europeu e configurar a fila lá. Em sua configuração de primavera, defina seus consumidores para consumir essa fila e outras filas em outros clusters. Você pode consultar os documentos:

http://activemq.apache.org/clustering.html

Ele pode garantir replicas de dados em pelo menos dois datacenters, se disponíveis? Novamente, acredito que sim, mas é melhor consultar os documentos de cluster.

Novamente, o JMS tem muitas opções que você pode ajustar conforme sua necessidade. O uso de sessões negociadas e filas duráveis ​​tem um custo de desempenho. Eu vi ligar todos os sinos e assobios impactando o desempenho em até 10x. Quando usei o JBossMQ, se desativássemos alguns desses recursos, poderíamos receber cerca de 10.000 mensagens / s, mas ativá-los nos reduziu a 1.000 mensagens / s. Grande queda.


Obrigado por dedicar um tempo com esta resposta. Uma divisão de rede é quando alguns nós em um cluster não podem mais se comunicar com o restante. Por servidores heterogêneos, quero dizer principalmente quantidades diferentes de RAM - alguns sistemas distribuídos preferem quando os servidores são parecidos.
Chris Vest

Então, com certeza, sim em netsplits. Se um consumidor cair ou não puder se comunicar, ele continuará tentando se conectar. Os trabalhos que lhe foram entregues e que não receberam uma confirmação serão posteriormente entregues a outros consumidores. Se um provedor JMS ficar inoperante e você tiver outros membros das mensagens do cluster, poderão ser duplicados no cluster para evitar a perda de mensagens.
Chubbsondubs

Não há requisitos para que as máquinas sejam idênticas, seja RAM, Hardware ou SO. Você pode executar um saco misto de máquinas, se necessário. A única preocupação é a que observei, relacionada ao desempenho, pois máquinas que não são iguais processarão mensagens a taxas diferentes, o que pode levar a uma taxa de transferência mais baixa. No entanto, o modelo JMS mitiga isso pelo fato de ser pull em vez de push. Os modelos push são muito mais sensíveis a esses tipos de problemas.
Chubbsondubs
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.