Sharding: um guia de decisão
- sharding
- banco-de-dados
- arquitetura
Publicado em por Gabriel Dias · 6 min de leitura · Engenharia
Índice errado você derruba e cria outro. Cache errado você desliga. Chave de shard errada você vai carregar por anos, e a correção é um projeto com dedicação de time, não uma tarefa de sprint.
Por isso este texto é menos sobre como fazer e mais sobre como decidir. E o primeiro conselho é impopular:
As quatro técnicas, e três delas você deveria esgotar primeiro
Particionamento vertical separa colunas. As que sempre são lidas juntas ficam numa tabela; as grandes e raramente lidas (o blob, o texto longo, o JSON de auditoria) vão para outra.
Ganho: cada página do disco cabe mais linhas úteis, e a varredura fica mais rápida. É a técnica mais
barata e a mais esquecida. Em tabelas com uma coluna text gigante, o ganho é imediato.
Particionamento funcional separa por domínio. Pedidos num banco, catálogo em outro, autenticação em outro. É o caminho natural para separação em serviços, e costuma dar mais alívio do que sharding, com muito menos dor, porque cada pedaço continua sendo um banco normal, com transações normais.
Particionamento horizontal nativo é o que Postgres, MySQL e outros oferecem como partições de
tabela. Você quebra uma tabela em pedaços dentro do mesmo banco, normalmente por data. A query que
filtra por data lê só as partições relevantes. E remover dado antigo vira DROP de partição, que é
instantâneo, em vez de DELETE em massa, que é doloroso.
Só depois disso vem sharding, que é distribuir as linhas entre bancos diferentes.
Faixa ou hash
Dentro do sharding, a primeira escolha.
Por faixa: clientes de A a M num shard, de N a Z noutro. Ou por data.
- Vantagem: consulta por faixa continua eficiente, porque os vizinhos estão juntos.
- Desvantagem: distribuição desigual. Se você particiona por data e todo mundo escreve hoje, um shard leva toda a carga de escrita e os outros ficam ociosos.
Por hash: você aplica hash na chave e distribui.
- Vantagem: distribuição uniforme quase de graça.
- Desvantagem: perdeu a consulta por faixa, pelo mesmo motivo que hash table não faz faixa: a função existe para espalhar.
A chave de shard: três critérios
Esta é a decisão que domina todas as outras.
Critério 1: ela distribui bem?
Se noventa por cento do tráfego tem o mesmo valor de chave, você não shardeou, só complicou. Olhe a distribuição real, com dado de produção, antes de decidir.
Critério 2: as suas consultas mais frequentes conseguem ir a um shard só?
Se a consulta principal precisa perguntar a todos os shards e juntar as respostas, você trocou uma query rápida por dez lentas mais uma agregação. Isso se chama scatter-gather, e é a maneira mais comum de tornar tudo pior.
E lembre da amplificação de cauda: com dez shards, a latência da sua consulta passa a ser a do shard mais lento dos dez.
Critério 3: ela é estável?
Chave que muda de valor obriga a mover o registro de shard. Prefira algo imutável. Identificador de cliente é bom; status de pedido é péssimo.
Na prática, em sistema de negócio, a chave costuma ser o identificador do cliente ou da conta, porque quase toda consulta é "as coisas deste cliente", e isso cai num shard só.
Os três problemas que sharding cria
E que raramente entram na reunião de decisão.
Acabaram as transações entre shards. O banco garante ACID dentro de um shard. Entre shards, você
precisa de saga ou de commit em duas fases. Toda operação que mexe em dois clientes ao mesmo tempo
(transferência, por exemplo) virou um projeto em vez de um BEGIN/COMMIT.
Acabaram os JOINs entre shards. Você vai desnormalizar de propósito, duplicando dado, e conviver com a inconsistência disso. Não é falha de projeto; é o preço.
Acabou a chave primária automática. Sequência de banco não funciona distribuída. Você vai usar UUID, ULID ou algo tipo Snowflake.
Um detalhe importante: se usar UUID versão 4, puramente aleatório, dentro de um índice B-tree, prepare-se para fragmentação e escrita espalhada. Prefira algo ordenável no tempo, como ULID ou UUIDv7, que mantém localidade de inserção.
Rebalanceamento e hash consistente
O jeito ingênuo de distribuir é hash da chave módulo o número de nós. Funciona lindamente até você adicionar um nó.
Com quatro nós, a chave vai para hash módulo quatro. Com cinco, para hash módulo cinco. Praticamente toda chave muda de lugar. Se for cache, você invalidou tudo de uma vez. Se for banco, você precisa mover quase todos os dados.
Hash consistente resolve. Imagine um círculo numerado; cada nó ocupa vários pontos nesse círculo, e cada chave pertence ao primeiro nó no sentido horário. Ao adicionar um nó, só as chaves entre ele e o anterior mudam de dono: aproximadamente um sobre N das chaves em vez de todas.
Os pontos múltiplos por nó (as réplicas virtuais) existem para uniformizar a distribuição. Com poucos pontos, o azar deixa a distribuição torta; com cento e cinquenta por nó, ela fica bem equilibrada.
Distribuir dado não é distribuir carga
Mesmo com chaves perfeitamente distribuídas, o tráfego pode ser desigual.
Chave quente: um registro específico recebe tráfego desproporcional: o post do influenciador, o produto em promoção, o cliente que é dez por cento da receita. O shard que hospeda aquela chave satura enquanto os outros ficam ociosos.
Soluções, em ordem de simplicidade: cache na frente para absorver leitura; replicar aquela chave com sufixos e escolher um ao acaso; para escrita concentrada, dividir em subchaves e agregar depois; e, em último caso, dar um shard dedicado ao cliente gigante, prática comum em sistema multi-tenant.
Shard quente: por desenho, uma faixa concentra a carga. O clássico é particionar por data.
E a detecção exige métrica por shard. Um painel com a média dos shards esconde exatamente o problema que você está procurando. Olhe o máximo e o desvio.
O checklist de decisão
Antes de shardear, responda por escrito:
- Já esgotei índice, cache, réplica, particionamento vertical e funcional?
- Qual é a chave, e como ela se distribui no meu dado real?
- Quais das minhas cinco consultas mais frequentes deixam de funcionar num shard só?
- Quais operações passam a precisar de saga?
- Como eu rebalanceio quando adicionar um shard?
- Como eu detecto chave quente?
Um e-mail por semana, sem enrolação
O que eu aprendi construindo software e IA na semana, em texto curto e direto, sem newsletter de 3 mil palavras. Cancele quando quiser.