Teorema CAP e consistência
A escolha obrigatória entre consistência e disponibilidade quando a rede se divide, e os níveis de consistência entre os dois extremos.
Mais de uma cópia do mesmo dado
Um único servidor de banco é simples: só existe uma versão de cada dado. Mas ele é um ponto único de falha e tem limite de capacidade. Por isso, os sistemas mantêm cópias:
- réplicas de leitura, que recebem as alterações do banco principal e atendem consultas;
- várias regiões, para atender usuários de perto e sobreviver à queda de um data center;
- caches, que guardam cópias dos dados mais lidos.
A partir do momento em que existem cópias, surge uma pergunta que um servidor único não tinha: todas as cópias estão iguais agora? Copiar leva tempo, e a rede entre as máquinas pode falhar.
O teorema CAP
O teorema CAP descreve três propriedades de um sistema com dados replicados:
| Letra | Propriedade | O que significa |
|---|---|---|
| C | Consistência | Toda leitura vê a escrita mais recente, como se existisse uma única cópia |
| A | Disponibilidade | Toda requisição a uma máquina que está funcionando recebe uma resposta, sem erro |
| P | Tolerância a partição | O sistema continua funcionando quando a rede entre as máquinas se divide |
A forma popular, "escolha duas das três", engana. Em qualquer sistema com mais de uma máquina, a rede vai falhar em algum momento: um cabo, um roteador, uma zona de nuvem isolada. A tolerância a partição não é opcional.
O teorema, então, diz o seguinte: quando a rede se divide, o sistema precisa escolher entre consistência e disponibilidade.
A escolha na prática
Imagine dois data centers com cópias do saldo de uma conta, e a conexão entre eles cai. Um cliente, conectado ao data center A, tenta sacar. O data center A não consegue saber se o saldo mudou no data center B.
| Escolha | O que o sistema faz | Consequência |
|---|---|---|
| Consistência (CP) | Recusa o saque, ou espera a rede voltar | O cliente recebe um erro, mas o saldo nunca fica errado |
| Disponibilidade (AP) | Aceita o saque com o saldo que conhece | O cliente é atendido, mas os dois lados podem aceitar saques que, juntos, passam do saldo |
Nenhuma das duas é errada em geral. Para um saldo bancário, a consistência costuma ser obrigatória. Para o contador de curtidas de uma publicação, mostrar um número um pouco velho é muito melhor do que mostrar um erro.
Mesmo sem falha: atraso e consistência
O CAP fala do momento da falha, que é raro. O que acontece o tempo todo é outra troca, descrita por uma extensão do teorema chamada PACELC: com partição (P), escolha entre disponibilidade (A) e consistência (C); senão (E, de else), escolha entre latência (L) e consistência (C).
Na operação normal, manter todas as cópias iguais exige esperar que cada escrita chegue às outras máquinas antes de confirmar. Isso custa tempo em toda escrita. Não esperar é rápido, mas deixa uma janela em que as cópias diferem.
Reproduzimos essa janela no PostgreSQL, com um banco principal e uma réplica de leitura, na configuração mais comum: replicação assíncrona. Com a aplicação das alterações pausada na réplica para simular um atraso:
escrita no principal: UPDATE pedidos SET status = 'pago' WHERE id = 981
o principal lê: pago
a réplica lê: aberto ← dado velhoNa operação normal, o atraso costuma ser de milissegundos. Sob carga, durante uma manutenção ou com a réplica longe, chega a segundos ou minutos. E qualquer leitura feita na réplica durante esse intervalo devolve o valor antigo.
Os níveis de consistência
Entre "todas as cópias sempre iguais" e "um dia elas ficam iguais" existem vários níveis. Os mais úteis no dia a dia:
| Nível | Garantia | Exemplo do que evita |
|---|---|---|
| Forte (linearizável) | Toda leitura vê a última escrita confirmada, de qualquer usuário | Dois clientes comprando o último item, cada um vendo estoque 1 |
| Ler as próprias escritas | O usuário sempre vê o que ele mesmo salvou | O endereço antigo depois de salvar o novo |
| Leituras monotônicas | O usuário nunca vê um dado mais velho do que um que já viu | Um comentário que aparece, some no próximo carregamento e volta |
| Causal | Se B foi escrito por causa de A, quem vê B também vê A | Ver a resposta de um comentário sem ver o comentário original |
| Eventual | Sem novas escritas, todas as cópias acabam iguais | Nada no curto prazo; só garante a convergência |
Um detalhe importante: muitos problemas reais são resolvidos com os níveis do meio, especialmente ler as próprias escritas, sem pagar o custo da consistência forte para todos os usuários.
Por que isso importa quando a IA escreve o código
Um assistente que configura réplicas de leitura ou um cache faz a parte da infraestrutura funcionar. Os efeitos de consistência ficam por conta de quem revisa:
- Todas as leituras passam a ir para a réplica, inclusive a que vem logo depois de uma escrita.
- Uma decisão de negócio, como aprovar um pedido ou conferir um saldo, é tomada com um dado lido da réplica.
- A tela mostra um valor do cache que acabou de ser alterado.
- O sistema é descrito como "consistente" sem que ninguém tenha definido o que isso significa para cada dado.
O próximo nível compara os sistemas pela escolha que fazem e mostra como decidir para cada tipo de dado.
Prompts para aprofundar
Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.
CAP em cinco minutos
Explique em no máximo cinco minutos de leitura o teorema CAP e o que significa consistência em sistemas com mais de uma cópia dos dados, para alguém que programa mas nunca trabalhou com réplicas. Cubra só o essencial: por que existem cópias, o que acontece quando a rede entre elas falha, a escolha entre responder com dado velho ou recusar, e por que ler de uma réplica pode trazer um dado velho mesmo sem falha. Use o exemplo de um saldo bancário e de um contador de curtidas. No final, me faça três perguntas curtas para eu verificar se entendi, e corrija as minhas respostas.
O teorema CAP sem simplificações
Quero entender o teorema CAP corretamente, sem a versão simplificada de "escolha duas de três". Aja como um mentor de sistemas distribuídos. Pergunte primeiro qual é a minha experiência. Conduza assim, uma etapa por vez: 1. Defina com precisão consistência, disponibilidade e tolerância a partição, como o teorema usa esses termos. 2. Explique por que a tolerância a partição não é opcional em sistemas com mais de uma máquina. 3. Descreva uma partição entre dois data centers e pergunte o que eu faria com uma escrita num sistema de reservas de passagens, antes de explicar as duas escolhas. 4. Explique a extensão PACELC e a troca entre latência e consistência na operação normal. 5. Mostre por que dizer "o banco X é CP" é uma simplificação. Faça uma pergunta de verificação em cada etapa e espere a minha resposta antes de continuar.
Os níveis de consistência com exemplos
Quero entender os níveis de consistência entre "forte" e "eventual", com exemplos concretos. Explique, um por vez, com um cenário de rede social ou de loja virtual em que cada um faz diferença: 1. Consistência forte (linearizável). 2. Ler as próprias escritas. 3. Leituras monotônicas. 4. Consistência causal. 5. Consistência eventual. Para cada nível, descreva o que o usuário veria se o sistema não oferecesse aquela garantia. Depois me apresente seis situações e pergunte qual é o nível mínimo necessário em cada uma. Corrija as minhas respostas.
O que acontece numa réplica atrasada
Quero entender o atraso de replicação na prática, com um banco relacional e uma réplica de leitura. Pergunte qual banco eu uso. Explique, para ele: 1. Como a replicação funciona: o registro de alterações, o envio para a réplica e a aplicação na réplica. 2. A diferença entre replicação síncrona e assíncrona, e o que cada uma garante em caso de queda do principal. 3. O que causa atraso na réplica: carga, consultas longas na réplica, rede, manutenção. 4. O sintoma típico na aplicação: o usuário salva e não vê o que salvou. 5. Como medir o atraso. Se possível, me ajude a montar um principal e uma réplica com Docker para eu ver o atraso acontecer, pausando a aplicação das alterações na réplica.