Implementando um serviço distribuído de n-produtores / 1 consumidor para sistema de missão crítica
Estou tentando implementar uma versão distribuída de multiprodutor / 1 consumidor para um sistema de missão crítica. Estou procurando boas alternativas para a abordagem atual baseada em RDBMS.

O problema
O sistema consiste em produtores de servidores (50+) que produzem continuamente milhares de instâncias por segundo. Cada instância é uma estrutura bem definida, com carimbo de data / hora e plana. Cada instância é armazenada em uma única fila pelos produtores.
Por outro lado, tenho um consumidor que consome as instâncias de forma FIFO.
Os produtores e o consumidor funcionam em máquinas diferentes conectadas por uma rede privada TCP / IP.
Para fins de integridade, existem dois requisitos fortes
- O consumidor não pode consumir o mesmo recurso duas vezes. É um erro.
- Todo recurso deve ser consumido pelo consumidor. Se um recurso for perdido, é uma perda
Além disso, a solução deve ser executada em servidores Linux e Windows.
Abordagem atual
Na versão atual, o sistema implementa esta solução utilizando um banco de dados relacional como barramento de dados.

Existe um servidor de banco de dados que oferece suporte a todos os produtores e consumidores. Os produtores inserem recursos em uma determinada tabela e o consumidor consome os recursos dessa tabela conforme representado na imagem acima.
O modelo de transação do servidor de banco de dados / JDBC permite controlar as inserções / exclusões para evitar a corrupção da fila.
Essa abordagem atual funciona bem, mas:
- Apresenta a sobrecarga de manter um servidor de banco de dados relacional completo para uma tarefa onde nenhum relacionamento de dados é necessário;
- O servidor de banco de dados relacional deve se ajustar aos requisitos de missão crítica, o que é difícil de conseguir em algumas configurações reais quando a instância do servidor de banco de dados não é dedicada
Alternativas
Aqui estou listando algumas alternativas para a abordagem atual do barramento de dados do servidor de banco de dados relacional:
Servidor dedicado de banco de dados relacional leve
Esta parece ser a abordagem mais fácil: usar um servidor de banco de dados relacional leve e dedicado como HSQLDB, Apache Derby ou H2.
Prós
Eles têm consideravelmente menos sobrecarga para manter se comparados com um RDBMS como o MS SQL Server, Oracle DB Server ou mesmo MySQL. Além disso, menos alterações de código e testes são necessários, uma vez que são basicamente mecanismos SQL como os usados na solução atual.
Contras
Eles são servidores de banco de dados relacionais, portanto, ainda existe algum nível de sobrecarga para executar uma tarefa sem relacionamento. Outro ponto é o aspecto da missão crítica. Usamos o Derby DB internamente por anos para surpervision do sistema em tempo real nos modos incorporado e de rede. Funciona muito bem, sem travamento nem corrupção de dados. No entanto, o volume de transações / s para esse novo uso é maior.
Servidor Redis
À primeira vista, o Redis parece perfeito para esse caso de uso. Na memória, rápido, sem overhad para relacionamento de dados, direto. Amplamente utilizado como barramento de dados e relatado como confiável. Mas não para o Windows. Como dito nos documentos, Redis no Windows não é recomendado . A versão do Microsoft Windows não é mais mantida , o último lançamento data de 2016, então anexar o Redis ao sistema não parece promissor.
Implementando uma solução do zero
Enfim, é um problema produtor-consumidor. Implementar um serviço de rede usando TCP ou algo mais elegante como Camel e usar fila simultânea internamente mais algum mecanismo de persistência local custará muito tempo, reinventar a roda, mas ainda é uma opção.
Essas são as alternativas que estamos considerando até agora. Agradeço se alguém puder fornecer algumas dicas ou recomendações.
Respostas
Parece que você está procurando uma fila de mensagens. Dependendo de sua pilha de tecnologia, existem várias implementações de fila distribuída que podem interessar a você, por exemplo ZeroMQ ou RabbitMQ.
Algumas abordagens como ZeroMQ podem ser executadas sem ter um intermediário de mensagem, o que significa que os produtores e consumidores conversam diretamente sem a necessidade de outro serviço ou banco de dados para orquestrar / intermediar a fila. Ser sem corretor tem a vantagem de ser muito mais simples de gerenciar operacionalmente do que filas de mensagens corretadas e ser mais simples de entender, escalar e personalizar, mas a principal desvantagem é que falta os serviços normalmente fornecidos por corretores, portanto, se um participante é off-line, as mensagens podem ser perdidas. Se você precisa que a mensagem seja processada de forma confiável, você precisará projetar seus produtores para serem capazes de lidar com a repetição do envio se o consumidor não estiver disponível, você precisará adicionar um mecanismo para confirmação da entrega bem-sucedida e as necessidades do consumidor ser projetado para ser idempotente (ser capaz de detectar mensagens duplicadas e descartá-las). A principal vantagem de não ter um corretor é que você é livre para implementar tanto ou tão pouco comportamento de corretor quanto seu aplicativo precisar, portanto, você não está vinculado a um comportamento de corretor específico.
Uma fila de mensagens intermediárias como RabbitMQ é um pouco mais simples durante o uso, pois o corretor adiciona uma camada de persistência e confiabilidade de mensagens à estrutura do sistema de fila em vez de exigir que o produtor e os consumidores as implementem, mas adiciona a complexidade e a sobrecarga de gerenciamento do corretor , e o corretor adiciona latência, portanto, pode ser inadequado para cenários em que os milissegundos importam ou onde o nível de escalabilidade de destino excede o que pode ser alcançado em um sistema intermediado.
ainda existe algum nível de sobrecarga para realizar uma tarefa sem relacionamento
Sugiro que você crie o perfil de seu aplicativo para descobrir se isso realmente importa ou não. Provavelmente, se um banco de dados SQL em processo não for suficiente para um aplicativo não simultâneo, é mais provável que você o esteja usando de maneira ineficiente, e não devido a problemas de desempenho no próprio gerenciamento de relacionamento.