DevGuideTK
← Trilha Backend

Escalabilidade

Escala vertical e horizontal, e o que precisa mudar no sistema para ele aceitar mais máquinas.

As decisões de escala são quatro: o que precisa mudar na aplicação para ela rodar em várias cópias, como escalar o banco de dados, quando escalar automaticamente e o que medir antes de qualquer coisa.

Preparar a aplicação para várias cópias

Cada tipo de estado que hoje mora na instância tem um lugar para onde ir:

EstadoPara onde vaiObservação
SessõesRedis, banco de dados, ou um token assinado no próprio clienteO tópico de autenticação compara as opções
Arquivos enviadosArmazenamento de objetos (S3, GCS, Azure Blob, MinIO)Com upload direto do navegador, os arquivos nem passam pela aplicação
CacheRedis para dados compartilhados; memória só para dados de referência, com TTL curtoO tópico de cache detalha
Tarefas agendadasUm agendador externo, ou uma trava que garante uma única execuçãoVer abaixo
Limites de requisiçõesContadores no RedisContados por usuário em todas as cópias
Conexões em tempo realUm canal de publicação e assinatura entre as cópiasUma mensagem para o usuário precisa chegar à cópia em que ele está conectado
ConfiguraçãoVariáveis de ambiente ou um serviço de configuraçãoNunca editar arquivos dentro de uma cópia em execução

Afinidade de sessão não é a solução

Os balanceadores oferecem afinidade de sessão (sticky sessions): o mesmo usuário vai sempre para a mesma cópia. Ela esconde o problema do estado na memória, mas não o resolve:

  • quando a cópia cai ou é substituída num deploy, os usuários dela perdem o estado;
  • a carga fica desigual, porque alguns usuários fazem muito mais pedidos que outros;
  • a escala automática fica lenta para reduzir, porque cada cópia tem usuários presos a ela.

Ela tem usos legítimos, como reduzir a troca de servidor em conexões de longa duração. Como forma de guardar estado, é um adiamento.

Tarefas agendadas com várias cópias

AbordagemComo funciona
Agendador externoUm CronJob do Kubernetes ou um agendador da nuvem dispara a tarefa uma vez, fora das cópias da aplicação
Trava no bancoTodas as cópias tentam rodar; só a que obtém a trava executa
Fila de tarefasO agendador publica uma mensagem, e um único consumidor a processa

A trava no banco é a solução mais simples quando já existe um PostgreSQL. O nível Implementação mostra como.

Escalar o banco de dados

O banco é a parte mais difícil de escalar, porque guarda o estado que a aplicação tirou de si. A ordem abaixo vai do mais barato para o mais caro, e a maioria dos sistemas nunca passa do meio da lista.

DegrauO que fazerCusto
1. Otimizar consultasÍndices, eliminar N+1, conferir planos de execuçãoBaixo; costuma render mais que todo o resto
2. Pool de conexõesLimitar e reaproveitar conexões; um intermediário como PgBouncer com muitas cópias da aplicaçãoBaixo
3. CacheTirar do banco as leituras repetidasMédio; traz o problema da invalidação
4. Escala verticalUma máquina maior para o bancoMédio; simples, com teto alto
5. Réplicas de leituraLeituras distribuídas entre cópiasMédio; traz atraso de replicação
6. Particionar tabelasDividir tabelas enormes por data ou por chave, no mesmo servidorMédio
7. Separar bancos por domínioPedidos num banco, catálogo em outroAlto; junções entre domínios deixam de existir
8. ShardingDividir os mesmos dados entre vários servidores, por chaveMuito alto; afeta consultas, transações e operação

Escala automática

Métrica para escalarQuando usarCuidado
Uso de CPUAplicações que gastam CPU por pedidoNão reage a gargalos de entrada e saída
Pedidos por segundo por cópiaAPIs com custo parecido por pedidoExige saber quantos pedidos uma cópia aguenta
Tamanho da filaConsumidores de mensagensO indicador mais direto para trabalho assíncrono
LatênciaQuando a experiência é o que importaSe o gargalo for o banco, mais cópias pioram a latência

Três regras evitam os problemas mais comuns:

  1. Um mínimo de pelo menos duas cópias, para que a queda de uma não derrube o sistema.
  2. Um máximo, calculado pelo que o banco e as dependências aguentam.
  3. Reduzir mais devagar do que aumentar, para não remover cópias que serão necessárias minutos depois.

Medir antes de escalar

PerguntaOnde olhar
Onde o tempo de cada pedido é gasto?Rastreamento distribuído, profiling
Qual recurso está no limite?CPU, memória, conexões e disco de cada componente
Quantos pedidos uma cópia aguenta?Teste de carga numa cópia isolada
Qual é o primeiro componente a falhar com o dobro da carga?Teste de carga no sistema inteiro

Um teste de carga antes de um evento esperado, como uma promoção, mostra onde o sistema vai quebrar enquanto ainda há tempo de agir. O tópico de testes de carga aprofunda.

Resumo da decisão

  1. Meça primeiro: escala resolve capacidade, e não lentidão de um pedido.
  2. Aplicação sem estado: sessões, arquivos, cache e tarefas fora da instância.
  3. Banco: otimizar, cache, máquina maior e réplicas, nessa ordem, antes de dividir dados.
  4. Escala automática com mínimo de duas cópias, máximo calculado e redução lenta.
  5. Cópias descartáveis: iniciam rápido e saem sem derrubar pedidos.

O próximo nível mostra o encerramento gracioso nas cinco linguagens, as verificações de saúde e a trava para tarefas agendadas.

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • Preparar a aplicação para várias cópias

    Quero preparar a minha aplicação para rodar em várias cópias atrás de um balanceador.
    
    Pergunte qual linguagem, framework e infraestrutura eu uso, e peça que eu descreva o que a aplicação guarda hoje: sessões, uploads, cache, tarefas agendadas, conexões em tempo real e configuração.
    
    Para cada item:
    1. Diga se ele impede a escala horizontal e por quê.
    2. Proponha para onde ele deve ir, com a opção mais simples para o meu caso.
    3. Estime o esforço da mudança.
    
    Explique também por que a afinidade de sessão esconde o problema em vez de resolvê-lo.
    
    Termine com um plano em ordem de prioridade e com a forma de testar localmente, com duas cópias atrás de um balanceador, que tudo funciona.
  • Escalar o banco de dados sem pular etapas

    Meu banco de dados está chegando ao limite e quero escolher o próximo passo certo.
    
    Faça estas perguntas, uma por vez:
    - Qual banco eu uso e em que máquina ele roda?
    - O que está no limite: CPU, memória, disco, conexões?
    - A carga é mais de leitura ou de escrita?
    - Quais são as consultas mais pesadas?
    - Quantas cópias da aplicação existem e qual é o tamanho de cada pool de conexões?
    
    Com as respostas, percorra comigo a escada: otimizar consultas, pool e intermediário de conexões, cache, máquina maior, réplicas de leitura, particionamento de tabelas, separação por domínio e sharding. Para cada degrau, diga se ele resolve o meu problema, o que custa e o que muda na aplicação.
    
    Recomende o próximo passo e o que medir para saber se funcionou.
  • Configurar a escala automática

    Quero configurar a escala automática da minha aplicação sem criar novos problemas.
    
    Pergunte onde a aplicação roda (Kubernetes, serviço de containers da nuvem, máquinas virtuais) e que tipo de carga ela tem.
    
    Explique:
    1. Qual métrica usar para escalar no meu caso: CPU, pedidos por segundo, tamanho de fila ou latência.
    2. Como escolher o mínimo e o máximo de cópias, considerando o que o banco e as outras dependências aguentam.
    3. Por que reduzir deve ser mais lento que aumentar.
    4. Como o tempo de inicialização das cópias afeta a reação a picos.
    5. Como testar a configuração antes de um evento real.
    
    Termine com a configuração recomendada para a minha plataforma.