ENGENHARIA DE SOFTWARE · LEITURA DE ~10 MIN

Padrões de Consistência
em Sistemas Distribuídos

Dois clientes compram o último exemplar do mesmo livro ao mesmo tempo. Qual serviço "ganha"? A resposta certa depende de um único fator: qual padrão de consistência o sistema escolheu — e essa escolha muda tudo sobre como ele se comporta sob pressão.

Padrões de consistência em sistemas distribuídos: serviços de pedidos, estoque, pagamento e réplica mostrando quando uma escrita vira verdade. A imagem resume consistência forte, fraca e eventual.

SEÇÃO 01

O que é um sistema distribuído

Antes de falar de consistência, vale alinhar uma ideia simples: um sistema distribuído é uma aplicação dividida em várias partes, cada uma rodando separado, que conversam entre si pela rede para entregar um resultado só.

Pega uma livraria online como exemplo. Em vez de um único servidor cuidando de tudo, a aplicação pode ser dividida assim:

Diagrama de uma livraria online distribuída: o cliente chama os serviços de Pedidos, Estoque e Pagamento, que também conversam com Contas, Fidelidade e E-mail pela rede.
SISTEMA DISTRIBUÍDO · UMA APLICAÇÃO, VÁRIOS SERVIÇOS

Cada serviço tem uma responsabilidade e, muitas vezes, o seu próprio banco de dados. Isso já foi coberto em detalhe no artigo sobre microsserviços na prática — aqui o interesse é outro: o que acontece com os dados quando eles ficam espalhados assim.

APROFUNDANDO

A definição mais citada é da Wikipédia: um sistema distribuído é um conjunto de componentes localizados em computadores diferentes na rede, que se comunicam e coordenam suas ações trocando mensagens entre si, para atingir um objetivo em comum.

SEÇÃO 02

Por que consistência é um problema

Quando os dados vivem em mais de um lugar, alguém precisa garantir que essas cópias não fiquem contando histórias diferentes. Volta pro exemplo da livraria: o Serviço de Estoque precisa saber, com precisão, quantos exemplares de um livro ainda existem no momento em que alguém tenta comprar.

Agora imagine dois clientes olhando pro mesmo livro — só resta 1 exemplar — ao mesmo tempo:

Condição de corrida: Cliente A e Cliente B compram ao mesmo tempo quando o estoque mostra um exemplar; sem controle de consistência, o estoque pode terminar negativo.
CONDIÇÃO DE CORRIDA · DOIS PEDIDOS PARA UM EXEMPLAR

Isso é uma condição de corrida clássica: entre o momento em que o Cliente B lê o estoque e o momento em que o Serviço de Estoque termina de processar a compra do Cliente A, a informação ficou desatualizada — e ninguém percebeu a tempo.

É exatamente esse tipo de problema que os padrões de consistência resolvem: eles definem quando, exatamente, uma escrita feita em um lugar se torna visível para uma leitura feita em outro.

SEÇÃO 03

As três famílias de padrões

Não existe uma resposta universal para "quando os dados devem sincronizar" — existe uma troca (trade-off) entre três coisas: quão rápido o sistema responde, quão disponível ele fica quando algo falha, e quão exata é a informação que ele entrega. Os padrões de consistência são as três formas mais comuns de fazer essa troca:

Três famílias de consistência: forte lê sempre a última escrita, fraca pode ler dado antigo e eventual converge com o tempo.
FORTE · FRACA · EVENTUAL

Repare que consistência eventual não é uma terceira categoria independente — é um caso específico, e bem comportado, de consistência fraca: ela não promete nada sobre quando a leitura vai refletir a escrita, só promete que, sem novas escritas, todas as cópias convergem pro mesmo valor com o tempo.

SEÇÃO 04

Consistência forte

Aqui a regra é simples de enunciar: depois que uma escrita termina, qualquer leitura seguinte — não importa de qual réplica — vê essa escrita imediatamente. Pra isso funcionar, a replicação precisa ser síncrona: todas as cópias são atualizadas antes de o sistema confirmar que a operação terminou.

Consistência forte: cliente envia uma transferência para um coordenador que espera as réplicas A, B e C confirmarem antes de responder.
CONSISTÊNCIA FORTE · REPLICAÇÃO SÍNCRONA

Um sistema financeiro é o exemplo clássico: ninguém pode ver o saldo de uma conta "quase" atualizado. O preço dessa garantia é claro — como o sistema precisa esperar todas as réplicas confirmarem antes de responder, ele tem latência mais alta e fica menos disponível quando uma réplica está fora do ar.

APROFUNDANDO

Essa troca tem nome: o Teorema CAP diz que, durante uma falha de rede entre réplicas (uma partição), um sistema distribuído só consegue manter duas de três garantias — Consistência, Disponibilidade e Tolerância a Partição. Como partição de rede é inevitável em produção, na prática a escolha real é entre consistência e disponibilidade quando as coisas dão errado. Consistência forte escolhe consistência; os outros dois padrões deste artigo escolhem disponibilidade.

SEÇÃO 05

Consistência fraca

Aqui a promessa é bem mais solta: depois de uma escrita, uma leitura seguinte pode ver essa mudança — ou pode não ver. Não existe garantia de prazo nem de ordem. Isso soa arriscado, mas é exatamente o que faz sentido quando velocidade importa mais do que precisão absoluta.

Consistência fraca em jogo online: a região principal vê o movimento na hora, um jogador com lag pode ver depois, e a partida não trava esperando todas as confirmações.
CONSISTÊNCIA FRACA · BAIXA LATÊNCIA

Numa plataforma de jogos multiplayer, as ações de um jogador aparecem na hora pra quem está no mesmo servidor. Se alguém tiver uma perda momentânea de conexão, essa pessoa pode não ver certas ações a tempo — e o jogo não trava esperando por isso. Isso gera inconsistência real entre o que cada jogador enxerga, mas também é o que permite alta disponibilidade e baixa latência, que é o que realmente importa numa partida em tempo real.

SEÇÃO 06

Consistência eventual

Consistência eventual pega a ideia de consistência fraca e adiciona uma promessa a mais: sem novas escritas chegando, todas as réplicas eventualmente convergem para o mesmo valor. A replicação acontece de forma assíncrona — o sistema responde antes de propagar a mudança pra todo mundo.

Consistência eventual: o usuário posta em São Paulo, Frankfurt e Singapura podem mostrar o estado antigo por alguns segundos, mas depois convergem para o mesmo valor.
CONSISTÊNCIA EVENTUAL · REPLICAÇÃO ASSÍNCRONA

Uma rede social é o exemplo mais intuitivo: os dados moram em vários datacenters ao redor do mundo, pensados pra alta disponibilidade e baixa latência. Quando alguém posta algo, essa atualização aparece na hora pra quem está no mesmo datacenter, mas leva um tempinho pra propagar pros outros. Durante essa janela, pessoas diferentes literalmente enxergam versões diferentes do mesmo feed — e isso é uma escolha de design, não um bug.

APROFUNDANDO

Na prática, "eventualmente" costuma vir com reforços: leitura de quórum (exigir resposta de N de M réplicas antes de considerar uma leitura válida, reduzindo a chance de ler um dado velho) e consistência causal (garantir que, se uma escrita depende de outra — como uma resposta que só faz sentido depois do comentário original —, a ordem entre as duas é respeitada, mesmo sem consistência forte no resto do sistema).

SEÇÃO 07

Comparando os três padrões

Colocando lado a lado, fica mais claro o que cada padrão troca pelo quê:

Tabela comparando consistência forte, fraca e eventual por latência, disponibilidade, integridade e replicação.
TRADE-OFFS · LATÊNCIA, DISPONIBILIDADE E INTEGRIDADE

Repare que nenhuma linha dessa tabela é "melhor" de forma absoluta — cada uma é a certa pra um tipo de problema diferente. É por isso que sistemas grandes de verdade quase sempre misturam os três padrões, cada um aplicado numa parte diferente da arquitetura.

SEÇÃO 08

Como escolher na prática

Antes de escolher um padrão, três perguntas ajudam a diagnosticar o que o dado realmente exige:

  • Um dado errado causa prejuízo real? Saldo de conta, estoque final de um pagamento único, permissão de acesso — isso pede consistência forte.
  • O sistema pode ficar fora do ar esperando sincronizar? Se a resposta for não, alguma forma de consistência fraca ou eventual costuma ser necessária.
  • Um pequeno atraso na propagação é aceitável? Curtidas, contagem de visualizações, feed de posts — quase sempre toleram consistência eventual sem ninguém notar.
Guia de decisão: dados que causam prejuízo real pedem consistência forte; dados que não podem esperar sincronização podem usar consistência fraca; dados que aceitam atraso pequeno podem usar consistência eventual.
DIAGNÓSTICO · COMO ESCOLHER O PADRÃO

Vale lembrar que essa escolha não precisa ser única para o sistema inteiro. Na própria livraria do início do artigo, o pagamento pode exigir consistência forte, enquanto a contagem de "quantas pessoas visualizaram esse livro hoje" tranquilamente aceita consistência eventual.

SEÇÃO 09

Conclusão

Consistência não é uma caixa de "sim ou não" — é um espectro, e cada ponto dele custa algo diferente:

RESUMOTEXTO
Consistência forte:
troca velocidade e disponibilidade por exatidão garantida.

Consistência fraca:
troca exatidão por velocidade e alta disponibilidade.

Consistência eventual:
aceita atraso temporário, mas garante que tudo converge.

A pergunta certa nunca é "qual padrão de consistência é o melhor" — é "o que esse dado específico não pode se dar ao luxo de errar, e o que ele pode se dar ao luxo de esperar". Responder isso, dado por dado, é o que separa uma arquitetura distribuída bem pensada de uma que só parece funcionar até o dia em que dois pedidos chegam ao mesmo tempo.

FIM · OBRIGADO POR LER

Quer ver essas decisões aplicadas num sistema inteiro?

O artigo de System Design mostra como cache, banco de dados e comunicação assíncrona se encaixam nas mesmas trocas de consistência, disponibilidade e latência discutidas aqui.

LER SYSTEM DESIGN VOLTAR AOS CONTEÚDOS