Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

04 - Desafios (Re-sharding, Consultas globais)

#2pc#consultas-globais#re-sharding#sagas#transacoes-distribuidas
video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

Desafios (Re-sharding, Consultas globais)

O sharding entrega escala horizontal de escrita e armazenamento, mas cobra o preço em moeda de complexidade distribuída: operações que eram locais no banco único passam a atravessar nós, redes e ciclos de consistência. Os quatro desafios maiores são o re-sharding, a redistribuição de dados em produção; as consultas globais, que não carregam a chave e varrem todos os fragmentos; as transações que cruzam shards, com dois-phase commit ou sagas; e o desbalanceamento, com hot shards dominando a capacidade do cluster. Nenhum desses desafios é bloqueante a ponto de inviabilizar o sharding em quem precisa dele; todos, porém, são caros o bastante para recomendar cautela a quem ainda não precisa. Este registro mapeia cada desafio com seus mecanismos de mitigação consolidados e fecha com os critérios que indicam quando o sharding não é a resposta certa.

Conceito: o preço estrutural da distribuição

O banco único esconde uma lista de facilidades que só aparecem como problema quando os dados se separam. Transações ACID cobrem qualquer conjunto de linhas; JOINs cruzam tabelas livremente; chaves únicas globais são garantidas pelo próprio motor; backups, índices e consistência referencial são administrados em um lugar. No sharding, cada uma dessas facilidades vira um projeto: transações precisam de protocolo distribuído, JOINs precisam de co-localização ou fanout, unicidade precisa de geradores globais de ID e a operação se multiplica pelo número de fragmentos.

O re-sharding é o desafio que fecha o ciclo, pois a própria distribuição criada precisa ser revista quando o volume cresce, quando a chave se mostra mal dimensionada ou quando shards individuais ficam quentes. A qualidade de uma plataforma de sharding pode ser medida pela dor dessas quatro operações, e times maduros as ensaiam antes de precisar delas.

Re-sharding em produção

Re-sharding é a operação de mudar o esquema de distribuição de dados vivos: aumentar o número de shards, alterar a chave ou trocar a estratégia. O motivo mais comum é crescimento simples, com shards alcançando limites de armazenamento ou de capacidade de escrita; o segundo é o hot shard, um fragmento que cresce desproporcionalmente; o terceiro é a correção de escolhas originais, como chave com cardinalidade insuficiente. Em qualquer variante, a operação repete um fluxo consagrado de quatro fases:

  • Fase de espelhamento: instalar a nova topologia e replicar os dados atuais para ela, sem afetar o tráfego, usando CDC, VReplication ou mecanismo equivalente de cópia com ponto de corte.
  • Backfill incremental: copiar o acervo histórico em lotes controlados, com limitação de banda para não saturar os nós de origem e com retomada idempotente após interrupções.
  • Camada dupla e validação: escrever simultaneamente nas duas topologias, comparar contagens, somas de verificação e amostras de linha, e medir o atraso de convergência.
  • Corte de tráfego: alternar leitura e escrita para a nova topologia por etapas, primeiro tráfego interno, depois leitura, por fim escrita, com reversão rápida disponível.

O corte por etapas é o que separa uma migração profissional de uma aposta: cada etapa tem critério de avanço e critério de reversão, e o sistema inteiro pode voltar à topologia anterior até o momento em que a escrita única se estabelece. A janela total tipicamente varia de dias a semanas, dominada pelo backfill do acervo histórico, e não pela lógica de roteamento.

# Plano de re-sharding em YAML: contrato operacional do evento
operacao: re-sharding-pedidos
origem:
  shards: 8
  chave: user_id
  estrategia: hash_modulo
destino:
  shards: 32
  chave: user_id
  estrategia: consistent_hashing
fases:
  espelhamento: { ferramenta: cdc_debezium, banda_max_mbps: 200 }
  backfill: { lote_linhas: 50000, pausa_entre_lotes_ms: 500 }
  validacao: { comparar: [contagem, checksum_por_lote], amostragem: 0.1 }
  corte: { etapas: [interno, leitura, escrita], reversao: por_etapa }
limites:
  atraso_cdc_max_seg: 30
  erro_validacao_max: 0

Ferramentas de resharding online

A operação manual de re-sharding é possível e alguns times a executam, mas a prática consolidada usa ferramentas que automatizam espelhamento, backfill e corte. A tabela compara as principais:

Ferramenta Ecossistema Mecanismo de migração Destaque
Vitess (VReplication) MySQL Fluxos de cópia contínua com corte controlado por workflow Padrão em escala de web massiva, usado por grandes plataformas
MongoDB reshardCollection MongoDB Redistribuição coordenada pelo próprio cluster Operação nativa, sem proxy externo
Citus PostgreSQL Rebalanceamento de shards distribuídos por metadata Extensão nativa, co-localização de tabelas
ShardingSphere MySQL, PostgreSQL Migração com proxy e scaling job Ecossistema Apache, configuração declarativa
Movimento manual Qualquer CDC, camada dupla e scripts próprios Controle total, custo de engenharia alto

A escolha da ferramenta é subordinada à plataforma de sharding já adotada; trocar de plataforma para obter resharding mais fácil raramente compensa. O ponto de atenção comum a todas é a capacidade de reversão: ensaiar o retorno à topologia original é parte do plano, não um extra.

Consultas globais e agregações entre shards

Consultas globais são as que não informam a chave de sharding: contagem de pedidos do dia, ranking de produtos, busca por nome de cliente. Cada uma delas vira scatter-gather, enviada a todos os fragmentos com resultados agregados em um coordenador. A latência passa a ser regida pelo shard mais lento, e o custo linear no número de nós transforma consultas globais frequentes em assassinas de capacidade.

As mitigações formam camadas. A primeira é paralelizar o fanout com limite de concorrência e agregação parcial por shard, que transforma a soma global em somas locais somadas no coordenador, reduzindo o tráfego de retorno. A segunda é o índice secundário global, mantido de forma assíncrona, que mapeia atributos de busca ao fragmento de destino ao custo de consistência eventual. A terceira é o offload analítico: consultas globais pesadas migram para um data warehouse ou motor colunar alimentado por CDC, deixando o cluster transacional com rota direta apenas. A quarta é o cache de resultado para agregações caras e tolerantes a defasagem, com TTL curto e invalidação por evento.

A regra de desenho que decorre disso é clássica: o cluster transacional shardado não é o lugar para analytics. Tentar servir BI sobre fragmentos transacionais degrada ambos os mundos, e a separação de camadas é mais barata que a guerra por recursos.

A medição do problema também tem camada própria: contar consultas globais por minuto, medir o fanout efetivo, isto é, quantos shards cada consulta toca, e registrar a latência do gather por endpoint. Com esses números, o time prioriza quais consultas merecem índice global, quais vão para o warehouse e quais permanecem como fanout aceitável, transformando o scatter-gather de vilão invisível em item gerenciado de backlog.

Transações distribuídas: 2PC e sagas

Quando uma transação precisa alterar linhas em dois shards, o banco único não ajuda mais, e duas famílias de protocolo disputam o caso. O two-phase commit, 2PC, coordenador propõe a mudança a todos os participantes, aguarda promessa de commit e então confirma; garante atomicidade, mas bloqueia recursos entre as fases, e um coordenador que falhe no meio deixa os participantes presos, situação clássica de indisponibilidade prolongada. Por isso a maioria dos sistemas de alta escala evita 2PC no caminho transacional quente.

As sagas dividem a transação em passos locais, cada um com transação ACID própria, e encadeiam ações de compensação para desfazer caminhos parciais em caso de falha. Um pedido que reserva estoque no shard A e grava cobrança no shard B executa dois passos locais; a falha no segundo dispara a compensação de liberação do estoque no primeiro. O resultado é eventualmente consistente, exige idempotência em cada passo e produz estados intermediários visíveis, que a interface precisa saber interpretar, como pedido com status reservando, confirmado ou cancelado.

Saga de pedido entre shards: passos locais com compensações
1. Reservar estoque (shard de produtos)     compensa: liberar estoque
2. Gravar cobrança (shard de pagamentos)    compensa: estornar cobrança
3. Confirmar pedido (shard do usuário)      compensa: marcar cancelado
Falha em qualquer passo executa as compensações dos passos anteriores
na ordem inversa, com idempotência garantida por chave de operação

A melhor transação distribuída, porém, é a que não existe: desenhar agregados co-localizados pela chave de sharding, como discutido no arquivo da chave, mantém a maioria absoluta das transações dentro de um único fragmento. O orçamento de transações cross-shard deve ser medido e mantido raro, e os casos inevitáveis adotam sagas com compensações explícitas.

Aspecto 2PC Sagas
Garantia Atomicidade forte Consistência eventual com compensação
Bloqueio de recursos Sim, entre as fases Não, cada passo é transação local
Falha do coordenador Participantes podem ficar presos Passos retomáveis com idempotência
Estados intermediários Invisíveis Visíveis, parte do desenho
Complexidade no código No motor ou coordenador Nos serviços, com lógica de compensação
Uso típico Coordenação de infraestrutura, lotes Caminho transacional de aplicações distribuídas

Desbalanceamento e hot shards

Hot shard é o fragmento que recebe carga desproporcional, seja por viés da chave, seja pela celebridade de uma entidade: o usuário viral, o inquilino corporativo gigante, o produto campeão de campanha. O sintoma é o cluster com nós ociosos e um nó em saturação, limitando a capacidade total ao pior fragmento. O diagnóstico vem do monitoramento por shard de CPU, I/O, contagem de linhas e latência por consulta.

As respostas seguem uma gradação. A divisão do shard quente redistribui seus intervalos ou arcos, útil quando o viés está na distribuição e não na entidade. O shard dedicado isola a entidade gigante em fragmento próprio, com dimensionamento individual, o desenho mais comum para inquilinos corporativos. O cache na frente da leitura quente absorve o tráfego de consulta sem tocar o banco. O salting da chave quente divide a escrita da entidade em subchaves, com agregação na leitura. Nenhuma dessas respostas é global; a escolha depende de o peso estar em leitura ou em escrita e de a origem ser distribuição ou entidade.

A prevenção também existe e é mais barata que qualquer resposta: escolher chaves de alta cardinalidade, monitorar o desvio de carga desde o primeiro dia e reservar margem de fragmentos para movimentação. Clusters sem margem livre transformam a divisão de um shard quente em evento de emergência, porque não há espaço para receber os dados movidos.

Quando NÃO shardar

O desafio mais barato de resolver é o sharding desnecessário, e os sinais de que ele é desnecessário aparecem antes de qualquer migração. Alternativas que resolvem a maioria dos casos sem a complexidade distribuída:

  • Escala vertical: classes de instância modernas oferecem CPU, memória e NVMe que sustentam terabytes transacionais; subir a classe é a solução mais barata enquanto ela alcança.
  • Réplicas de leitura: a maior parte das cargas tem proporção de leitura dominante, e réplicas resolvem esse lado sem tocar o caminho de escrita.
  • Caching distribuído: um cache adequado retira a leitura quente do banco e frequentemente posterga qualquer projeto de sharding em anos.
  • Particionamento e arquivamento: particionamento no servidor resolve manutenção de tabelas grandes, e arquivamento para armazenamento frio corta o acervo quente.
  • Ajuste de workload: índices corretos, consultas ajustadas, transações curtas e filas para escritas diferidas resolvem mais saturação do que qualquer redistribuição.
  • Bancos novos com armazenamento elástico: motores com camada de armazenamento separada e compute escalável postergam o teto físico e mudam o cálculo do gatilho.

Os gatilhos legítimos de sharding continuam sendo limites físicos reais: escrita que não acompanha na maior classe disponível, acervo que excede o armazenamento do nó, requisitos regulatórios de residência por cliente e isolamento contratual forte. Fora desses casos, a recomendação prática é tratar o sharding como seguro de escala de último recurso, contratado quando o risco é comprovado, e não como status de arquitetura.

Erros comuns e boas práticas

  • Erro: re-sharding em evento único, com parada de escrita e esperança de que tudo funcione; prática: fases de espelhamento, backfill, validação e corte por etapas com reversão.
  • Erro: ignorar o backfill e descobrir que semanas de cópia saturaram os nós de origem; prática: limitação de banda, lotes pequenos e métrica de atraso de CDC durante toda a migração.
  • Erro: aceitar consultas globais frequentes no caminho transacional; prática: offload analítico, índices globais seletivos e cache de agregação para o resto.
  • Erro: usar 2PC por padrão para qualquer transação entre shards; prática: co-localizar agregados para eliminar a transação distribuída e reservar sagas para os casos remanescentes.
  • Erro: tratar hot shard como problema de infraestrutura quando é problema de entidade; prática: diagnóstico por entidade quente, com shard dedicado, cache ou salting conforme o caso.
  • Erro: executar o corte de tráfego sem ensaio prévio em ambiente de staging; prática: simulação completa das quatro fases com dados sintéticos e métricas comparadas antes do evento real.
  • Erro: shardar por motivo de reputação técnica com carga que cabe em um nó; prática: exaurir vertical, réplicas, cache e particionamento, e shardar apenas com gatilho físico comprovado.

A visão final do módulo é equilibrada: o sharding é a ferramenta que quebra o teto físico do banco único, e os desafios listados aqui são o custo conhecido e administrável dessa quebra. Times que os antecipam com co-localização de agregados, roteamento disciplinado, ferramentas de resharding ensaiadas e camada analítica separada operam clusters de milhares de fragmentos com tranquilidade; times que os descobrem em produção pagam cada lição com incidente. A decisão madura começa sempre pela pergunta oposta: o que precisa acontecer para este sistema realmente precisar de sharding.