antonio leandro

sistemas distribuídos

Millions of Tiny Databases

paper · núcleo · Marc Brooker, Tao Chen, Fan Ping · · ~49 min de leitura do original

a tese

consistência forte e disponibilidade sob partição só brigam se você exigir disponibilidade para todos os clientes; cada chave precisa viver em três pontos da rede, então não construa um banco — construa milhões

o que fica

  1. Um banco não precisa estar disponível para todos os clientes: cada chave do Physalia só precisa ser alcançável de três pontos da rede — a instância EC2, a cópia primária e a réplica.
  2. O tamanho da cell é uma aposta estatística: cells pequenas se saem pior sob falhas aleatórias isoladas e melhor quando mais da metade dos nós cai de uma vez.
  3. Physalia não aceita ponto flutuante nem inteiro de precisão limitada, porque nós com versões e hardware diferentes precisam aplicar a mesma transição com resultado idêntico.
  4. O princípio de Postel não vale para máquina de estado replicada: aceitar uma transação que você entende só em parte faz o estado divergir — o certo é recusar e deixar o consenso te tratar como falho.
  5. Em Paxos, uma reconfiguração aceita na posição i do log só pode valer em i+α, onde α é a profundidade do pipeline; essa aresta não existe em Raft nem em Viewstamped Replication.
  6. Control plane é posição privilegiada e perigosa: o do Physalia apagou cells corrompidas por enxergá-las como vazias, e ganhou rate limit e um botão vermelho depois disso.

o problema

O EBS replica cada volume em cadeia: cliente, primário, réplica. Em operação normal ninguém coordena nada — os dados fluem pela cadeia e pronto. Quando o primário morre, alguém precisa dizer, de forma atômica e bem ordenada, qual é a nova composição do grupo de replicação. Esse alguém é o configuration master, e ele tem um perfil de carga esquisito: quase nenhum tráfego no dia a dia, uma explosão de trabalho exatamente durante falhas de energia ou partições de rede, latência crítica (o IO do volume fica bloqueado até a resposta) e consistência forte obrigatória, porque qualquer consistência eventual torna o protocolo de replicação incorreto. Ele é mais necessário no pior momento possível.

Em 21 de abril de 2011, uma mudança de configuração de rede mal executada deixou 13% dos volumes de uma AZ indisponíveis. Na época a configuração de replicação morava no control plane do EBS, dividindo banco com o tráfego de API. Cada volume que tentava se re-espelhar abria uma negociação com esse control plane; como o re-espelhamento não terminava, as chamadas se multiplicavam em retries e novas requisições, o control plane sofreu brown out e as APIs do EBS caíram na região inteira. Physalia nasceu desse postmortem.

a ideia

Gilbert e Lynch já provaram que não dá para ter linearizabilidade e disponibilidade para todos os clientes sob partição. Consistência é inegociável aqui. Mas “todos os clientes” é uma exigência que ninguém fez: cada chave só precisa estar disponível em três pontos da rede. Se o banco souber onde esses três pontos estão, ele pode se mudar para perto deles e ficar do lado certo da partição quase sempre.

Daí o nome. A caravela portuguesa (Physalia physalis) não é um animal, é uma colônia de zooides especializados, cada um um organismo completo que não sobrevive fora do conjunto. Uma instalação Physalia é uma colony feita de milhões de cells minúsculas e independentes.

como funciona

Cada cell guarda os dados de uma única partition key — um volume EBS — e é uma máquina de estado replicada por Paxos sobre sete nós. Cells não conversam entre si; um nó participa de muitas cells, e o control plane garante que cada nó tenha uma mistura diferente delas, para que um poison pill derrube uma cell e não um conjunto correlacionado.

Sete é um número escolhido a dedo: a durabilidade cresce exponencialmente com o tamanho da cell (sete réplicas dão pelo menos quatro discos, cerca de 5.000 vezes mais durável que a replicação dupla dos dados do volume), cells maiores absorvem melhor nós lentos em pausa de GC, e cells menores só perdem em disponibilidade quando as falhas são poucas e descorrelacionadas.

O placement usa a topologia de rede e de energia lida da automação do datacenter. Num datacenter idealizado com racks, rows e três domínios de energia, a cell fica toda na row do cliente — não adianta estar de pé se a row caiu — espalhada por pelo menos três racks e três domínios de energia, sem maioria em nenhum. Quando o cliente se move, a cell persegue: o control plane troca um nó distante por um próximo de cada vez, esperando o novo alcançar o log, e a mudança inteira costuma terminar em menos de um minuto.

A API é inspirada na do DynamoDB: batch atômico, conditional write, incremento in-place, mais uma operação composta de leitura-e-escrita-condicional. Os tipos são byte array, inteiro de precisão arbitrária e boolean. Nada de float, nada de inteiro de precisão limitada, nada de SQL — tudo que arrisca dois nós com versões diferentes chegarem a resultados diferentes fica de fora.

Nós que entram ou voltam são atualizados por teaching: snapshot completo para nó novo, trecho de log para quem ficou para trás numa pausa de GC, e whack-a-mole (propor um no-op na posição vazia) para buracos persistentes. Clientes acham as cells por um discovery cache eventualmente consistente, com cache local, ponteiros de encaminhamento e muitas réplicas — informação errada ali afeta liveness, nunca correção. E cada cell recebe uma cor: deploys andam cor por cor, e nós de cores diferentes não se falam.

o que isso custou

Os autores admitem que um monolito seria mais simples, e que simplicidade melhora disponibilidade. Physalia paga discovery cache, control plane, criação e movimentação de cells. Não é tolerante a bizantinos: HMAC nas mensagens e descarte do que não autentica, nada além disso. As leases toleram skew de relógio, mas dão resultado errado se o relógio mais rápido anda mais de três vezes mais que o mais lento — por isso nunca são usadas onde a integridade do dado depende delas. Placement globalmente ótimo é intratável e online, então usam uma heurística barata de trocas aleatórias entre cells, com vinte candidatos.

Sob carga a cell rejeita transações quando o pipeline enche e espera backoff exponencial do cliente: estabilidade em troca de latência no pior momento. E simulação de falha na camada de agregação mostra até 29% dos volumes chamando Physalia ao mesmo tempo.

O incidente mais instrutivo veio de um bug na ferramenta de deploy que fez rollback para uma versão antiga em alguns nós. Eles simplesmente ignoraram um conditional que não entendiam, o estado divergiu, e o control plane leu as cells corrompidas como vazias e as deletou.

onde isso aparece hoje

Physalia roda em produção em mais de 60 availability zones, servindo milhares de requisições por segundo por AZ, com leituras abaixo de 10 ms no p99 e escritas tipicamente abaixo de 50 ms. Contra o sistema legado que substituiu, a melhora na taxa de sucesso da primeira chamada do primário é estatisticamente clara.

O verbete que ele conversa mais de perto é Brewer’s Conjecture: Physalia é uma resposta de engenharia ao teorema, não uma tentativa de burlá-lo. O núcleo é Paxos sem invenção nenhuma, e a linhagem de serviços de coordenação passa por Chubby, do qual Physalia se separa por ter consenso de granularidade fina em vez de um único log. A API vem do DynamoDB, deliberadamente estreita.

Fora isso, o paper exporta duas práticas. O simworld — rede, relógio e disco atrás de interfaces, com implementações em memória e injeção de falha no nível do pacote — permite escrever um teste de partição em menos de dez linhas de Java que roda em menos de 100 ms; o time escreveu centenas deles. E TLA+, usado menos como prova e mais como documentação precisa e verificável dos protocolos, à qual code reviews e reuniões de design voltavam para desempatar ambiguidade.

lido na íntegra por pipeline de llm, revisado por antonio leandro antes de publicar ·