Sem memória compartilhada, sem relógio compartilhado e com uma rede que mente
Uma fã no trem toca em Reservar assento. O spinner gira por 5 s, depois "Algo deu errado". Ela toca de novo. O primeiro toque reservou um assento? Ela vai reservar dois? Ser cobrada duas vezes?
"Um sistema distribuído é aquele em que a falha de um computador que você nem sabia que existia pode tornar o seu próprio computador inutilizável." — Leslie Lamport
Em escala, falhar é a regra: 1 − (1 − p)N. Com p = 0,1% por máquina por dia, 3.000 máquinas veem uma falha em ~95% dos dias.
inventory
SeatHeld
payment
/health
As falhas que doem não são crashes limpos: são as lentas, as parciais e as cinza.
Deutsch et al., Sun Microsystems (1994; Gosling acrescentou a 8ª em 1997). Cada uma volta em uma aula posterior.
inventory → payment: autorizar R$ 450 … silêncio … timeout após 2 s.
inventory → payment: autorizar R$ 450
Timeouts são um trade-off (longo demais: threads se acumulam; curto demais: alarmes falsos e carga extra). Retries precisam ser seguros → idempotência.
Efetivamente uma vez = entrega pelo menos uma vez + processamento idempotente.
"Entrega exatamente uma vez" sem ressalvas é um sinal de alerta em uma entrevista.
GET
PUT
DELETE
POST
x = x + 1
UPDATE seats SET status = 'HELD', fan_id = 42, hold_key = :key WHERE id = 'A-12' AND (status = 'FREE' OR hold_key = :key);
Quando dizer OK: assíncrona (rápida, pode perder escritas no failover) · síncrona (o seguidor mais lento decide) · semissíncrona / quórum (o meio-termo usual).
A fã paga às 10:00:41 e abre Meus ingressos 300 ms depois — servido por uma réplica assíncrona. A lista está vazia.
Corrija com precisão: read-your-writes, não consistência forte global.
P não é opcional — "CA" não é escolha para dados replicados. E o C do CAP é linearizabilidade, não o C do ACID.
Partição → A ou C; senão (Else) → Latência ou Consistência.
Por isso: síncrona entre zonas (EC), assíncrona ou particionada por região de origem entre regiões (EL). Ordens de grandeza ilustrativas.
UPDATE
Multirregião: cada evento tem uma região de origem (a do local do show) — a consistência forte fica local, e uma partição só afeta reservas entre regiões.
Use 3 ou 5 nós, espalhados de modo que nenhuma zona tenha a maioria. Dois nós a 99% cada = 98,01%.
term + 1
AppendEntries
Padrões do etcd: heartbeat de 100 ms, election timeout de 1.000 ms → a queda de um líder custa ~1–2 s sem escritas. Usado por etcd, Consul, CockroachDB, Kafka KRaft.
ONE
QUORUM
ALL
A sobreposição é necessária, não suficiente: quóruns relaxados, escritas concorrentes e LWW ainda produzem anomalias. Consistência ajustável ≠ consenso.
UPDATE scheduled_jobs SET last_run_at = now(), fencing_token = :token WHERE job_id = 'onsale-reminder-42' AND fencing_token <= :token;
BoxOffice: Patroni + etcd de 3 nós elege o primário PostgreSQL; o primário antigo se rebaixa. Use consenso, não o construa.
O coordenador cai depois dos votos → os participantes ficam em dúvida, o assento A-12 fica travado. As disponibilidades se multiplicam (todos no ar ao mesmo tempo), duas idas e voltas + fsyncs, e o provedor de pagamentos não pode participar.
O 2PC continua vivo dentro de bancos distribuídos com coordenador replicado (Spanner, CockroachDB, transações do Kafka) — não entre microsserviços.
PENDING
CANCELLED
RESERVED_FOR_PAYMENT
SOLD
CONFIRMED
order
currentTimeMillis
nanoTime
Last-write-wins com um nó 50 ms adiantado: uma liberação em .040 carimbada .090 vence uma reserva em .060 → a Carla pagou e ficou sem assento. O relógio mais adiantado vence todo conflito.
sql
nosql
cache
cdn
dns
thirdparty
queue
stream
kafka
scheduler
Todo componente do playground herda um desses problemas — pergunte qual antes de colocá-lo num projeto.
R + W > N
Roteiro: (1) por que distribuir e modelos de falha; (2) a rede não confiável, timeouts e idempotência; (3) replicação e modelos de consistência; (4) CAP e PACELC; (5) consenso e quóruns; (6) tempo e relógios.