Estruturar para aumentar horizontalmente
Conceber uma aplicação para ser dimensionada horizontalmente
Uma das principais vantagens da nuvem é o dimensionamento elástico — a capacidade de usar a capacidade necessária, dimensionar à medida que a carga aumenta e dimensionar quando a capacidade extra não é necessária. Projete seu aplicativo para que ele possa ser dimensionado horizontalmente, adicionando ou removendo instâncias, combinando oferta e demanda.
A escalabilidade é medida pela proporção entre o ganho de taxa de transferência e o aumento de recursos. Idealmente, em um sistema bem projetado, ambos os números são proporcionais: uma alocação dupla de recursos dobrará o rendimento. A escalabilidade é normalmente limitada pela introdução de gargalos ou pontos de sincronização dentro do sistema.
Recomendações
Evite a persistência de instâncias. A persistência, ou afinidade da sessão, é quando os pedidos do mesmo cliente são sempre encaminhados para o mesmo servidor. A aderência limita a capacidade de expansão do aplicativo. Por exemplo, o tráfego de um usuário de alto volume não será distribuído entre instâncias. As causas de persistência incluem armazenar o estado da sessão na memória e utilizar chaves específicas da máquina na encriptação. Certifique-se de que todas as instâncias conseguem processar qualquer pedido.
Identifique os estrangulamentos. Aumentar horizontalmente não é uma solução mágica para todos os problemas de desempenho. Por exemplo, se a base de dados de back-end estiver estrangulada, não ajuda adicionar mais servidores Web. Identifique e resolva primeiro os estrangulamentos no sistema, antes de atirar mais instâncias para o problema. As partes com monitorização de estado do sistema são a causa mais provável dos estrangulamentos.
Decomponha as cargas de trabalho consoante os requisitos de escalabilidade. Na maioria das vezes, as aplicações são constituídas por várias cargas de trabalho, com diferentes requisitos de dimensionamento. Por exemplo, uma aplicação pode ter um site destinado ao público e um site de administração separado. O site público pode ter picos de tráfego repentinos, enquanto que o site de administração tem uma carga mais pequena e previsível.
Projete componentes autônomos e dissociados que se comunicam por meio de protocolos de comunicação assíncronos. Idealmente, os componentes devem ter seu próprio estado independente e usar eventos para comunicar qualquer alteração ou atividade a componentes externos. Isso ajuda a dimensionar de forma independente apenas o componente sobrecarregado. Implemente mecanismos de controle de fluxo para gerenciar o tráfego e degradar graciosamente. Os consumidores devem controlar a sua própria taxa de consumo. Os produtores devem controlar a sua própria taxa de transmissão, incluindo a interrupção. As filas de mensagens são boas opções para absorver a carga de trabalho extra e permitir que os consumidores drenem o trabalho à vontade.
Evite comunicação, coordenação e espera desnecessárias.
Descarrega tarefas naturalmente assíncronas. Tarefas como enviar e-mails, ações em que o usuário não precisa de uma resposta imediata e integração com outros sistemas são bons lugares para fazer uso de padrões de mensagens assíncronas.
Descarregue as tarefas com muitos recursos. As tarefas que exigem uma grande quantidade de recursos da CPU ou de E/S devem ser movidas para trabalhos em segundo plano sempre que possível, para minimizar a carga no front-end que está a processar os pedidos de utilizador.
Dimensionamento automático com base em métricas de uso em tempo real e use recursos de dimensionamento automático integrados. Muitos serviços de computação do Azure têm suporte incorporado para dimensionamento automático. Se a aplicação tiver uma carga de trabalho normal previsível, aumente horizontalmente com base numa agenda. Por exemplo, aumente horizontalmente durante o horário comercial. Caso contrário, se a carga de trabalho não for previsível, utilize métricas de desempenho, tais como o comprimento da fila de pedidos ou da CPU para acionar o dimensionamento automático. Observe os aplicativos e suas comunicações para identificar gargalos e tomar decisões mais precisas. Para obter as melhores práticas para o dimensionamento automático, veja Dimensionamento automático.
Considere um dimensionamento automático agressivo para cargas de trabalho críticas. Para cargas de trabalho críticas, quer manter-se à frente da exigência. É melhor adicionar novas instâncias rapidamente em cenários de muita carga para processar o tráfego adicional e, em seguida, reduzir gradualmente.
Conceba para reduzir horizontalmente. Não se esqueça de que, no dimensionamento elástico, a aplicação terá períodos de redução horizontal quando as instâncias forem removidas. A aplicação tem de processar graciosamente as instâncias que são removidas. Seguem-se algumas formas de lidar com a redução horizontal:
- Escute os eventos de encerramento (quando disponíveis) e encerre corretamente.
- Os clientes/consumidores de um serviço devem suportar a repetição e o processamento de falhas transitórias.
- Para tarefas de longa execução, considere dividir o trabalho através de pontos de verificação ou do padrão Pipes e Filtros.
- Coloque os itens de trabalho numa fila para que outra instância possa recolher o trabalho, caso uma instância seja removida durante o processamento.
Considere o dimensionamento para redundância. A expansão pode melhorar a confiabilidade do seu aplicativo. Por exemplo, considere a expansão em várias zonas de disponibilidade, como o uso de serviços com redundância de zona. Essa abordagem pode melhorar a taxa de transferência do seu aplicativo, bem como fornecer resiliência se uma zona sofrer uma interrupção.
Modele e otimize a escalabilidade do seu sistema. Você pode usar o modelo do seu sistema usando uma abordagem como a lei de Amdahl. Quantifique a escalabilidade com base em parâmetros como contenção e coerência. Contenção refere-se a atraso devido a espera ou fila para recursos compartilhados. A coerência refere-se ao atraso para que os dados se tornem consistentes. Por exemplo, ter uma alta contenção indica um processamento sequencial que pode ser paralelizado, enquanto ter uma alta coerência sugere dependências excessivas entre processos, levando você a minimizar as interações. Durante o projeto da carga de trabalho, você pode calcular a capacidade efetiva máxima do seu sistema para evitar fornecer mais oferta do que demanda, o que leva ao desperdício.