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:
- 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.
- Introduzir balanceador de carga: mesmo que haja apenas um servidor no início, o balanceador prepara o terreno para adicionar mais nós.
- Implementar cache distribuído: reduz a carga no banco de dados e permite que múltiplas instâncias compartilhem dados em cache.
- Refatorar para microsserviços: dividir o monolito em serviços independentes que podem ser escalados separadamente.
- 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
- The Art of Scalability: Vertical vs Horizontal Scaling — Artigo da NGINX explicando as diferenças fundamentais e quando usar cada abordagem.
- AWS Well-Architected Framework: Reliability Pillar — Documentação oficial da AWS sobre estratégias de escalabilidade em cloud.
- Martin Fowler: Microservices and Scalability — Artigo clássico sobre como microsserviços habilitam escalabilidade horizontal.
- MongoDB Sharding Documentation — Guia oficial sobre sharding horizontal em bancos de dados NoSQL.
- HAProxy Configuration Guide for Load Balancing — Documentação técnica sobre balanceamento de carga para escalabilidade horizontal.
- Google SRE Book: Handling Load — Capítulo do livro de Engenharia de Confiabilidade do Google sobre estratégias de escalabilidade.
- Redis: Distributed Caching Patterns — Padrões de cache distribuído para suportar escalabilidade horizontal.