Cluster de Servidor (Django, Apache, Nginx, Postgres)

3

Eu tenho um projeto implantado com o django, Apache, Nginx e Postgres. O projeto tem a necessidade de dados ativos visíveis para os clientes. Os principais pontos do projeto são: 1. Os dispositivos no campo enviam dados para o servidor (os dispositivos também são como os usuários do site) após o login. 2. Existe um processo de importação em segundo plano que importa os dados carregados no postgres. 3. Os webusers do sistema usam esses dados e podem enviar comandos para os dispositivos, que são lidos pelos dispositivos quando eles fazem o login. 4. Existem também rotinas de análise em segundo plano em execução nos dados.

Todos os sistemas e configurações mencionados acima são implantados em uma máquina de nuvem amazon EC2. Atualmente, o projeto suporta mais de 600 dispositivos e 400 usuários. Mas como o número de dispositivos está aumentando com o tempo, o desempenho do servidor está diminuindo.

Queremos estender esse projeto para que ele possa suportar mais e mais dispositivos. Meu pensamento inicial é: Vamos criar mais um servidor como o atual e dividir os dispositivos entre eles para servidores. Mas Novamente Precisamos de um ponto de gerenciamento central de usuários e dispositivos através do django admin.

Alguma idéia? Quais são as melhores maneiras possíveis de criar uma arquitetura escalonável? Como posso criar um cluster do Postgres e usá-lo com o Django, se possível?

    
por user38827 07.05.2010 / 16:23

2 respostas

4

Sua pergunta é curta em detalhes e longa na mão-acenando, mas parece que seu pensamento inicial é um começo muito bom. Seu aplicativo parece bastante semelhante ao Zenoss Monitoring Suite, que usa essencialmente a mesma arquitetura de distribuição de carga para escalar: Vários hosts de monitoramento compartilhando a carga de trabalho de coleta de dados, com uma única interface administrativa e um banco de dados no host admin ou em um separado sistema.

Se o seu gargalo estiver no ponto # 1 (dispositivos enviando dados para o seu servidor), dividir essas tarefas em uma segunda máquina deve criar algum espaço para o crescimento da carga. O maior obstáculo à implementação é geralmente como gerenciar tarefas através de múltiplos servidores Django. O aipo, um mecanismo de fila de tarefas distribuídas, é provavelmente a melhor opção no momento. Ele foi originalmente projetado em torno do Django, o que é bom para você, e tem uma comunidade muito ativa e útil de desenvolvedores e usuários.

Se os pontos 2 e 4 forem sua limitação atual, você provavelmente está falando sobre a escalabilidade do banco de dados. Em geral, trata-se apenas de um problema difícil: não há uma maneira barata, transparente e neutra quanto ao código de ampliar a capacidade do banco de dados.

Se você só precisa obter mais banco de dados para "ler" a capacidade de IO, a replicação provavelmente fará o truque. O Postgres suporta replicação usando uma ferramenta externa chamada Slony-I. A replicação é de um único mestre, com múltiplos hosts "escravo" somente de leitura que recebem cópias de instruções executadas no mestre. Todas as gravações do seu aplicativo (UPDATE, INSERT, DELETE ...) passam pelo host mestre único, mas você distribui suas leituras (SELECT ...) pelo mestre e todos os escravos.

As modificações de código necessárias para leituras distribuídas são geralmente bastante diretas. O Django recentemente adicionou suporte para bancos de dados replicados, os quais eu não usei, mas deve ser muito bom.

Se você precisar de mais capacidade de E / S de gravação de banco de dados, o sharding provavelmente funcionará. Cada host mantém um bloco separado e exclusivo de cada tabela de banco de dados. Os clientes de banco de dados usam uma função determinística para decidir onde qualquer registro deve residir, portanto, a distribuição de carga é efetivamente sem estado e pode ser dimensionada para um grande número de servidores de banco de dados. O novo suporte multi-banco de dados do Django (mesmo link acima) também suporta sharding. Você precisará de algumas alterações no código, a dor deve ser limitada.

Além disso, quero mencionar o Memcached, que parece fazer parte de praticamente todos os aplicativos da Web altamente escalonáveis na Internet hoje (Facebook, Google, Twitter ...). Uma boa implementação de cache pode reduzir seus requisitos de banco de dados a uma fração do seu tamanho original, convertendo pesquisas de banco de dados caras e lentas em pesquisas de cache rápidas e baratas. O Django suporta a integração do Memcached por um bom tempo, agora.

Eu percebo que nada disso é muito específico, mas deve dar a você um ótimo ponto de partida para trabalhar os detalhes. Boa sorte com seu projeto.

    
por 07.05.2010 / 17:55
0

Primeiro você deve perceber, onde está o seu botellneck? Problema da camada de aplicação? Acesso à camada de dados? Qual é o seu padrão de acesso? Principalmente lê? Ou talvez principalmente escreve?

Para camada de aplicativo:

  • adicionando mais servidores de aplicativos
  • algumas ações podem ser colocadas na fila de tarefas sem que o usuário aguarde o término (por exemplo, comandos para dispositivos)

Para a camada de dados, existem algumas maneiras que você pode seguir:

  • Pense na sua carga de trabalho? Você poderia reduzir algumas consultas? Você poderia mudar seu esquema? Talvez adicionando alguma desnormalização (pré-computando estatísticas, agregando dados). Para tabelas muito grandes, você provavelmente poderia adicionar o particionamento vertical
  • Para dimensionamento de leitura, você poderia usar a replicação, como Ryan B. Lynch
  • Armazenamento em cache com o memcached ou algo semelhante. Mas lembre-se: "Há apenas duas coisas difíceis na Ciência da Computação: invalidação de cache e nomeação de coisas."
  • Eu não recomendo sharding (particionamento horizontal), porque o gerenciamento do banco de dados sharded é doloroso. Aqui está um bom artigo sobre fragmentação.
  • Divida seus dados em diferentes backends de dados. Aqui está um bom artigo descrevendo a ideia.
por 14.08.2010 / 19:36