Escalabilidade horizontal vs vertical

1. Introdução à Escalabilidade em Arquitetura de Software

Escalabilidade é a capacidade de um sistema lidar com cargas crescentes de trabalho sem degradação significativa de desempenho. Em arquitetura de software, esse atributo é crítico para sistemas modernos que precisam atender a picos de tráfego, crescimento orgânico de usuários e aumento no volume de dados. Sem um planejamento adequado, um sistema bem projetado pode colapsar sob pressão.

Quando falamos em escalabilidade, duas abordagens fundamentais se destacam: escalabilidade vertical (scale-up) e escalabilidade horizontal (scale-out). A primeira consiste em adicionar mais recursos a uma única máquina; a segunda, em adicionar mais máquinas ao sistema. Escolher entre elas impacta diretamente custo, complexidade operacional e resiliência.

2. Escalabilidade Vertical (Scale-Up)

Escalabilidade vertical significa aumentar a capacidade de processamento de um único servidor. Isso pode ser feito trocando a CPU por um modelo mais potente, adicionando mais memória RAM, substituindo discos por SSDs mais rápidos ou expandindo a largura de banda de rede.

Vantagens:

  • Simplicidade: não exige alterações na arquitetura do software. A aplicação continua rodando em uma única instância.
  • Baixa latência interna: comunicação entre componentes ocorre dentro do mesmo hardware, sem overhead de rede.
  • Licenciamento mais simples: muitos bancos de dados relacionais (como Oracle ou SQL Server) cobram por instância, não por núcleo.

Limitações:

  • Teto físico: toda máquina tem um limite máximo de CPU, RAM e armazenamento. Após esse ponto, não é possível escalar mais.
  • Custo exponencial: servidores de alto desempenho custam muito mais do que o dobro de servidores médios. Por exemplo, um servidor com 64 núcleos pode custar 10x mais que um com 16 núcleos.
  • Ponto único de falha: se a máquina cair, todo o sistema para. A recuperação depende de hardware redundante, o que aumenta ainda mais o custo.

Exemplo prático – upgrade vertical:

# Cenário: aplicação web com banco de dados PostgreSQL
# Situação atual: servidor com 8 GB RAM e 4 CPUs
# A aplicação começa a apresentar lentidão em picos de 500 requisições/minuto

# Upgrade vertical:
# - Aumentar RAM para 32 GB
# - Substituir CPU por modelo com 16 núcleos
# - Trocar HDD por SSD NVMe

# Resultado: suporta até 2000 requisições/minuto
# Problema: quando o tráfego atingir 3000 req/min, será necessário novo upgrade

3. Escalabilidade Horizontal (Scale-Out)

Escalabilidade horizontal consiste em adicionar mais servidores (nós) a um cluster, distribuindo a carga entre eles. É a abordagem preferida para sistemas cloud-native e microsserviços.

Vantagens:

  • Elasticidade: é possível adicionar ou remover nós dinamicamente conforme a demanda, pagando apenas pelo que usa.
  • Tolerância a falhas: se um nó falha, os outros continuam atendendo. O sistema como um todo permanece disponível.
  • Custo linear: servidores commodity (hardware padrão) são baratos. Dobrar a capacidade custa aproximadamente o dobro.

Desafios:

  • Complexidade de coordenação: é necessário gerenciar estado distribuído, consistência de dados e descoberta de serviços.
  • Balanceamento de carga: o tráfego precisa ser distribuído uniformemente entre os nós.
  • Consistência de dados: em bancos de dados distribuídos, garantir que todos os nós vejam os mesmos dados exige protocolos como Raft ou Paxos.

Exemplo prático – escala horizontal:

# Cenário: API REST com banco de dados MongoDB
# Um servidor suporta 1000 requisições/segundo
# Previsão de crescimento para 10000 requisições/segundo

# Solução horizontal:
# - Adicionar 9 servidores idênticos ao cluster
# - Configurar balanceador de carga (Nginx ou HAProxy) na frente
# - Usar sharding no MongoDB para distribuir os dados

# Comandos de configuração (exemplo conceitual):
# 1. Criar 10 instâncias de aplicação idênticas
# 2. Configurar HAProxy:
#    frontend api_frontend
#        bind *:80
#        default_backend api_servers
#    backend api_servers
#        balance roundrobin
#        server app1 10.0.0.1:3000 check
#        server app2 10.0.0.2:3000 check
#        ... (até app10)
# 3. No MongoDB, configurar shard key por user_id

# Resultado: suporta 10000 req/s com resiliência

4. Comparação Técnica e Trade-offs

Característica Vertical Horizontal
Custo inicial Alto (hardware premium) Baixo (commodity)
Custo incremental Exponencial Linear
Complexidade Baixa Alta
Tolerância a falhas Baixa (ponto único) Alta (redundância)
Latência Baixa (mesmo hardware) Pode ser maior (rede)
Limite máximo Teto físico Teoricamente ilimitado

Desempenho vs custo: para cargas moderadas (até ~10k requisições/segundo), a escalabilidade vertical pode ser mais econômica pela simplicidade operacional. Acima disso, a horizontal se torna mais barata.

Latência: sistemas horizontais podem sofrer latência adicional devido à comunicação entre nós. No entanto, a distribuição geográfica permite colocar servidores mais perto dos usuários, reduzindo latência de rede.

5. Padrões Arquiteturais para Escalabilidade Horizontal

Balanceamento de Carga

Algoritmos comuns:

# Round Robin: distribui requisições sequencialmente
# Vantagem: simples, sem estado
# Desvantagem: não considera carga real de cada servidor

# Least Connections: envia para o servidor com menos conexões ativas
# Vantagem: melhor distribuição de carga real
# Desvantagem: requer monitoramento de conexões

# IP Hash: usa hash do IP do cliente para fixar sessão
# Vantagem: mantém afinidade de sessão (sticky sessions)
# Desvantagem: distribuição pode ser desigual

Sharding de Banco de Dados

Consiste em particionar os dados horizontalmente. Cada shard armazena um subconjunto dos registros.

# Exemplo: sharding por user_id
# Shard 1: user_id de 1 a 100000
# Shard 2: user_id de 100001 a 200000
# Shard 3: user_id de 200001 a 300000

# Consulta: SELECT * FROM usuarios WHERE user_id = 150000
# Roteamento: direciona para Shard 2

Filas e Workers

Para processamento assíncrono, filas como RabbitMQ ou Redis permitem desacoplar produtores de consumidores.

# Fluxo:
# 1. Requisição chega ao servidor web
# 2. Servidor publica mensagem na fila "processamento"
# 3. Workers (múltiplas instâncias) consomem da fila
# 4. Cada worker processa uma tarefa independente
# 5. Resultado é armazenado ou enviado de volta

# Vantagem: workers podem ser escalados horizontalmente sem afetar o frontend

6. Quando Escolher Vertical vs Horizontal

Prefira escalabilidade vertical quando:

  • Sistema legado que não pode ser reescrito (ex: ERP monolítico)
  • Banco de dados relacional com consultas complexas que exigem joins pesados
  • Carga previsível e moderada (até ~5000 usuários simultâneos)
  • Equipe pequena sem expertise em sistemas distribuídos

Prefira escalabilidade horizontal quando:

  • Aplicações web com picos de tráfego imprevisíveis
  • Microsserviços ou arquiteturas baseadas em eventos
  • Big data e processamento em lote (ex: Hadoop, Spark)
  • Necessidade de alta disponibilidade (99.99% ou mais)

Abordagem híbrida: muitos sistemas usam ambas. Por exemplo, cada nó de um cluster pode ser escalado verticalmente até um limite, e depois novos nós são adicionados horizontalmente. É comum ver bancos de dados com sharding horizontal onde cada shard roda em hardware verticalmente escalado.

7. Estratégias de Transição e Migração

Migrar de uma arquitetura vertical para horizontal sem downtime requer planejamento cuidadoso.

Passos recomendados:

  1. Separar estado da lógica: tornar os serviços stateless. O estado deve ser armazenado em cache distribuído (Redis, Memcached) ou banco de dados externo.
  2. Introduzir balanceador de carga: mesmo que haja apenas um servidor no início, o balanceador prepara o terreno para adicionar mais nós.
  3. Implementar cache distribuído: reduz a carga no banco de dados e permite que múltiplas instâncias compartilhem dados em cache.
  4. Refatorar para microsserviços: dividir o monolito em serviços independentes que podem ser escalados separadamente.
  5. Adicionar filas: para operações que não precisam de resposta imediata (envio de email, processamento de imagens).

Métricas para decidir o momento de escalar:

# Métricas críticas:
# - CPU > 80% sustentado por mais de 5 minutos
# - RAM > 85% de uso
# - Latência de resposta > 500ms para o percentil 95
# - Throughput próximo ao limite do hardware
# - Taxa de erros HTTP 5xx > 1%

# Para escala vertical: quando as métricas indicam gargalo e há margem para upgrade
# Para escala horizontal: quando o custo do próximo upgrade vertical supera 2 servidores médios

8. Conclusão e Boas Práticas

A escolha entre escalabilidade horizontal e vertical não é binária, mas estratégica. Sistemas bem-sucedidos geralmente combinam ambas as abordagens, usando vertical para componentes que exigem baixa latência e consistência forte, e horizontal para partes que precisam de elasticidade e tolerância a falhas.

Recomendações práticas:

  • Comece simples: um servidor vertical bem dimensionado resolve a maioria dos casos iniciais.
  • Projete pensando no futuro: mesmo sistemas pequenos devem ter serviços stateless para facilitar a transição.
  • Monitore continuamente: métricas de desempenho guiam decisões de escalabilidade.
  • Automatize: use orquestradores como Kubernetes para gerenciar clusters horizontais.
  • Teste sob carga: simule picos de tráfego para validar a estratégia antes de ir para produção.

Em última análise, a escalabilidade não é apenas sobre adicionar recursos, mas sobre projetar sistemas que possam crescer de forma previsível e sustentável. O arquiteto de software deve entender os trade-offs de cada abordagem e aplicar a combinação certa para cada contexto.


Referências