Ajuste de desempenho de um aplicativo distribuído
Nesta série, percorremos vários cenários de aplicativos em nuvem, mostrando como uma equipe de desenvolvimento usou métricas e testes de carga para diagnosticar problemas de desempenho. Esses artigos se baseiam em testes de carga reais que realizamos ao desenvolver aplicativos de exemplo. O código para cada cenário está disponível no GitHub.
Cenários:
- Transação comercial distribuída
- Chamada a vários serviços de back-end
- Processamento de streaming de eventos
O que é o desempenho?
O desempenho é frequentemente medido em termos de taxa de transferência, tempo de resposta e disponibilidade. As metas de desempenho devem ser baseadas em operações comerciais. Tarefas voltadas para o cliente podem ter requisitos mais rígidos do que tarefas operacionais, como a geração de relatórios.
Defina um SLO (objetivo de nível de serviço) que estabeleça metas de desempenho para cada carga de trabalho. Normalmente, você consegue alcançar esse objetivo dividindo uma meta de desempenho em um conjunto de KPIs (indicadores chave de desempenho), como:
- Latência ou tempo de resposta de solicitações específicas
- Número de solicitações realizadas por segundo
- Taxa de geração de exceções pelo sistema.
As metas de desempenho devem incluir explicitamente uma meta de carga. Além disso, nem todos os usuários recebem exatamente o mesmo nível de desempenho, ainda que acessem o sistema simultaneamente e executem o mesmo trabalho. Portanto, um SLO deve ser enquadrado em termos percentuais.
Um exemplo de SLO para esse caso pode ser: “As solicitações do cliente têm uma resposta em até 500 ms a P90, em cargas de até 25 mil solicitações/segundo”.
Desafios do ajuste de desempenho de um sistema distribuído
Pode ser especialmente desafiador diagnosticar problemas de desempenho em um aplicativo distribuído. Alguns dos desafios são:
Uma única operação ou transação comercial geralmente envolve vários componentes do sistema. Pode ser difícil obter uma exibição holística de ponta a ponta de uma única operação.
O consumo de recursos é distribuído entre vários nós distintos. Para obter uma exibição consistente, você precisará agregar logs e métricas em um único local.
A nuvem oferece escala elástica. O dimensionamento automático é uma técnica importante para lidar com picos de carga, mas também pode mascarar problemas subjacentes. Além disso, pode ser difícil saber quais componentes precisam ser dimensionados e em que momento.
As cargas de trabalho geralmente não são escaladas entre núcleos ou threads. É importante entender os requisitos das suas cargas de trabalho e buscar tamanhos mais otimizados. Alguns tamanhos oferecem núcleos restritos e hyperthreading desabilitado para aprimorar as cargas de trabalho licenciadas por núcleo e orientadas para núcleo único.
Falhas em cascata podem causar erros upstream do problema raiz. Como resultado, o primeiro sinal do problema pode aparecer em um componente diferente da causa raiz.
Práticas recomendadas gerais
O ajuste de desempenho é uma arte e uma ciência, mas ele pode se tornar mais próximo da ciência ao adotar uma abordagem sistemática. Eis algumas melhores práticas:
Habilite a telemetria para coletar métricas. Instrumentalize seu código. Siga as melhores práticas de monitoramento. Use o rastreamento correlacionado para que seja possível exibir todas as etapas de uma transação.
Monitore os percentuais 90/95/99, não apenas a média. A média pode mascarar exceções. A taxa de amostragem das métricas também é importante. Se a taxa de amostragem for muito baixa, ela poderá ocultar picos ou exceções que possam indicar problemas.
Ataque um gargalo de cada vez. Formule uma hipótese e teste-a alterando uma variável de cada vez. A remoção de um gargalo geralmente revela outro mais adiante, upstream ou downstream.
Erros e repetições podem ter um grande impacto sobre o desempenho. Se você perceber que os serviços de back-end estão limitando o sistema, escale horizontalmente suas operações ou tente otimizar o uso (por exemplo, ajustando as consultas do banco de dados).
Procure antipadrões de desempenho comuns.
Procure oportunidades de paralelizar. Duas fontes comuns de gargalos são as filas de mensagens e os bancos de dados. Em ambos os casos, a fragmentação pode ajudar. Para obter mais informações, confira Particionamento horizontal, vertical e funcional de dados. Procure as partições quente que podem indicar cargas de leitura ou gravação desbalanceadas.
Próximas etapas
Leia os cenários de ajuste de desempenho