System Design/02 - Componentes/Databases2 min
Sharding
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
Particionar horizontalmente os dados entre vários bancos independentes. Cada shard guarda um subconjunto das linhas.
É a única técnica que escala escrita — e a mais cara em complexidade permanente.
Estratégias de particionamento
| Estratégia | Como | Ponto fraco |
|---|---|---|
| Por intervalo | A-M no shard 1, N-Z no 2 |
Hot shard se a distribuição for desigual |
| Por hash | hash(chave) % N |
Distribui bem; rebalancear remapeia tudo |
| Consistent hashing | Anel com nós virtuais | Rebalanceia só 1/N; o padrão |
| Por diretório | Tabela de lookup chave→shard | Flexível; o diretório vira SPOF |
| Geográfica | Por região | Latência e soberania; desigual |
A escolha da shard key
É a decisão do sharding, e é quase irreversível. Uma boa chave tem: alta cardinalidade, distribuição uniforme, e — o mais importante — aparece na maioria das consultas. Se a query não traz a shard key, ela vira scatter-gather: consulta todos os shards e agrega.
Trade-offs
O que se perde ao particionar:
| Perde | Consequência |
|---|---|
| Junções entre shards | Compor na aplicação ou desnormalizar |
| Transação multi-shard | Precisa de 2PC ou Compensating Transaction |
AUTO_INCREMENT global |
UUID, Snowflake, ou faixas por shard |
| Consulta ad-hoc | Vira scatter-gather, lenta |
| Simplicidade operacional | Backup, migração e schema em N bancos |
Hot shard é o modo de falha característico: uma chave popular (um cliente gigante, um produto viral) concentra tráfego num shard, e nenhuma quantidade de shards adicionais resolve — o problema é a distribuição, não o número.
Rebalanceamento é a operação difícil. Com hash % N, adicionar um shard remapeia quase todas as chaves. Consistent hashing reduz a ~1/N, e ainda assim mover terabytes com o sistema no ar exige dupla escrita, migração incremental e um período de leitura de ambos os lados.
Por isso a regra: shard por último. Esgote SQL Tuning, Caching, Replication, Federation e Denormalization antes. E, quando shardar, prefira um banco que já faça isso nativamente a construir o particionamento na aplicação.
Exemplo prático
Um sistema multi-tenant particionado por tenant_id.
Funciona bem porque quase toda consulta filtra por tenant — logo, quase toda consulta atinge um shard só. Junções dentro do tenant continuam possíveis, porque os dados dele estão juntos.
Até que um cliente cresce e sozinho ocupa 40% do volume: o shard dele satura enquanto os outros ficam ociosos. É o hot shard, e a saída é dar a esse tenant um shard dedicado — mais uma exceção para o diretório de roteamento gerenciar.
Um relatório que cruza todos os tenants, por sua vez, precisa consultar todos os shards e agregar na aplicação. Em SQL não particionado, seria um GROUP BY.
Relacionado
Parte de Databases · roadmap.sh/system-design