Como implementar uma arquitetura em cluster leve para um aplicativo distribuído

5

Atualmente, tenho um aplicativo distribuído que é executado em vários PCs incorporados. A aplicação inteira é composta de um servidor mestre e vários nós. Cada nó é um PC embarcado que executa o Windows 7 Embedded e possui um processador dual core com 2 GB de RAM.

O aplicativo (por definição) só funciona se o mestre estiver ativo e em execução, controlando todos os nós. O servidor mestre tem um banco de dados SQL Express, onde ele mantém informações sobre cada nó que deveria controlar e como eles são organizados. Os nós não têm estado persistente.

Uma vez que o mestre e os nós estejam ativos e em execução, eles serão manipulados e colocados em um determinado estado, que é mantido apenas na memória neste momento. O mestre pode ser controlado por uma UI do cliente WinForm que se conecta a ele e pode ler seu estado e enviar comandos que alterarão seu estado (é basicamente um conjunto de serviços da Web expostos usando o .NET WCF).

O estado mantido dentro do mestre (na memória) é o que importa. O estado dentro de cada nó pode ser regenerado se um nó for reiniciado por exemplo. Se o mestre for reiniciado, ele perderá seu estado atual (e o nó será conseqüência). Isso significa que, após a reinicialização do servidor mestre, a configuração será recarregada e um estado "novo" será definido.

Normalmente, uma configuração desse aplicativo consiste em um mestre e nove nós (essa é uma configuração 3x3). A qualquer momento, um nó pode falhar e o aplicativo continuará sem ele (contanto que o mestre esteja ativo). Se o nó que falhou retornar, o mestre o detectará e retornará ao estado desejado.

Fui solicitado a melhorar a arquitetura desse aplicativo para que o servidor mestre possa ser executado dentro de um dos nós. Então, em vez de uma configuração 9 + 1, teremos apenas 9 PCs embutidos com um escolhido para ser um mestre. De acordo com nossos testes, o hardware do nó tem energia suficiente para suportar o nó e a obra mestre juntos. No entanto, o PC embarcado não é confiável e falhará com muito mais frequência do que um servidor comum que usamos para hospedar o mestre até agora.

Por causa disso, fui solicitado a criar uma solução de redundância. No meu entender, a solução adequada seria colocar dois ou mais sistemas de execução incorporados em clusters, portanto, se o nó que está executando a obra-mestre falhar, outro assumirá que é o local.

Agora, a pergunta é: como implementar um cluster leve que possa ser executado nessas condições?

Existem duas preocupações principais que devem ser resolvidas:

  1. Persistência de dados: não apenas a configuração deve ser salva, mas também o estado mestre. Dessa forma, quando o nó mestre for desativado, outro nó poderá assumir como mestre sem redefinir todo o estado do aplicativo.
  2. Clustering WCF: a qualquer momento, se o nó mestre falhar, outro deverá assumir e todos os clientes conectados (a UI do cliente WinForm) deverão poder se reconectar automaticamente ao novo nó mestre reeleito. Isso não precisa ser realmente transparente para o usuário, mas os clientes devem poder se reconectar automaticamente (não importa se o novo endereço IP será o mesmo ou não).

Existem vários fatores limitantes para uma possível solução:

  • Não há como ter um armazenamento de dados compartilhado entre os nós (cada nó tem seu próprio HD e uma rede gigabit privada entre eles)
  • Atualizações de hardware estão fora de questão
  • A solução precisa ser leve o suficiente para ser executada em um PC embarcado. Então instalar um servidor de nuvem ou um banco de dados em cluster provavelmente não será rápido o suficiente (se você acha que o MySQL em cluster funcionará para resolver a camada de dados, eu estarei interessado em ouvir seus pensamentos)
  • A solução não pode envolver a compra de um software caro
  • A plataforma geral deste aplicativo deve ser baseada no Windows

A melhor solução que pensei até agora foi usar algo como Prevayler para manter o estado mestre persistente e implementar uma sincronização de cada comando mestre recebido nos outros nós. Isso resolverá o problema de persistência em todos os nós (talvez algo semelhante possa ser implementado usando o memcache, não tenho certeza). Ainda não tenho solução para resolver o problema do serviço WCF.

Como isso envolverá muito desenvolvimento e testes adequados, eu pensei que deveria ouvir de vocês antes de implementar qualquer coisa.

Acho que uma solução poderia ser montada usando uma estrutura ou algum tipo de software de código aberto que resolva parte do problema.

Por favor, sinta-se à vontade para perguntar qualquer coisa para que eu possa melhorar o texto desta pergunta para torná-la mais clara.

    
por Alex 22.09.2011 / 08:06
fonte

2 respostas

2

Como você está se afastando de um único nó mestre (o que é apropriado), você precisará alterar algumas coisas. Você precisará configurar um Quórum . Já que você já tem 9 nós, você está em boa forma. Para um Quorum funcionar, você precisa de 2n + 1 nós, onde (n) é o número de nós que podem diminuir e o sistema ainda funcionará. Dentro do Quórum, haverá uma votação sobre quem é o líder e quais transações são bem-sucedidas. Isso pode ser usado para passar informações de configuração e garantir que todos estejam sincronizados sem um banco de dados.

Existem tecnologias existentes por aí que podem ajudá-lo com isso. Um desses é o ZooKeeper . É um produto Apache v2 de código aberto para Coordenação Distribuída. Você precisará de algo nesse sentido. Se ele está usando o ZooKeeper ou rolando o seu próprio white papers será inestimável. Também pode ser usado para manter suas informações de configuração sobre cada nó.

O ZooKeeper é escrito em Java, mas eu criei um projeto ( ZooKeeperNet que permitirá que ele seja embutido no aplicativo .NET usando IKVM. Se isso não for aceitável, leia sobre Eleições ao líder Ao determinar quem será o atual nó mestre, sugiro ler todas as páginas e receitas do Wiki para ter uma idéia do que você precisa considerar em um sistema distribuído adequado.

Só para você ter um bom entendimento. ZooKeeper é o sistema de coordenação de apoio do Hadoop e HBase. O Hadoop é uma estrutura distribuída de Mapeamento / Redução.

Se você ainda não estiver, poderá usar informações adhoc ou de descoberta de registro do WCF ao tentar localizar o nó mestre atual em seu sistema. Se apenas um único nó mestre estiver ativo, ele será o único registrado para suportar recursos do IMaster. Então, seus nós escravos irão escutar os znodes uns dos outros para irem embora, pegando o Mestre quase imediatamente.

Tenha em mente que, para ser altamente eficiente, os dados com os quais cada nó precisa trabalhar precisam estar próximos (isto é, no próprio nó) ao nó. Se um nó atuar como um intermediário de dados, você não será tão eficiente quanto poderia se os nós pudessem extrair dados de maneira distribuída.

    
por 22.09.2011 / 13:11
fonte
0

AMQP

Use uma implementação AMQP para garantir que as atualizações dos nós sejam enviadas para todos mestres. Isso cuidará de ter os dados em todos os mestres sincronizados. Existem implementações livres de AMPQ (assim como não-livres). Você provavelmente deseja executar algum teste para descobrir as tolerâncias apropriadas, etc. As interconexões Gigabit suportarão um pouco de comunicação enfileirada, supondo que a taxa de atualização não seja extremamente alta e a atualização média não seja enorme. YYMV, então você definitivamente vai querer rodar alguns números e fazer alguns testes para fazer backup.

Balanceamento de carga de rede com um IP de cluster

Uma maneira típica de manipular o balanceamento de carga é endereçar um único IP de cluster. Eu não sei muito sobre essa solução além de ser bastante comum no Windows. (é usado no meu trabalho um pouco)

    
por 22.09.2011 / 09:57
fonte