antonio leandro

sistemas distribuídos

The Chubby lock service for loosely-coupled distributed systems

paper · núcleo · Mike Burrows · · ~59 min de leitura do original

a tese

um serviço central de locks grosseiros resolve eleição de líder melhor que uma biblioteca de paxos — não por ser mais correto, mas porque cabe em duas linhas de código num sistema que já existe

o que fica

  1. Um lock distribuído sozinho não protege nada: o pedido de um dono que já morreu pode chegar depois, e é o sequencer — uma string opaca que o cliente repassa ao servidor de destino — que permite rejeitá-lo.
  2. Escalar o Chubby não é otimizar o caminho de leitura do master: 93% das RPCs são KeepAlive, e todo ganho veio de reduzir conversa com o servidor, não de acelerá-lo.
  3. Cache invalidado explicitamente ganha de cache por TTL porque ninguém precisa escolher o timeout: um fluxo constante de KeepAlives mantém um número arbitrário de entradas válidas indefinidamente.
  4. O grace period de 45s existe para que a sessão do cliente sobreviva à eleição de um novo master; sem ele, cada fail-over derrubaria locks que custam caro para recuperar.
  5. Locks grosseiros são uma decisão de carga, não de semântica: como um primário eleito segura o lock por horas, a taxa de aquisição não acompanha a taxa de transações dos clientes.
  6. O Chubby virou o serviço de nomes do Google sem que ninguém planejasse isso, e o paper trata o próprio erro de previsão como o achado principal.

o problema

Antes do Chubby, os sistemas do Google elegiam primário de dois jeitos ruins. Quando duplicar trabalho não fazia mal, cada equipe inventava seu método ad hoc. Quando a correção importava, alguém acordava um operador. Eleger primário entre pares é consenso distribuído sobre rede assíncrona, e isso o Paxos resolve — o Google até mantinha uma biblioteca cliente de Paxos, independente do Chubby. Só que usar essa biblioteca exige que o serviço seja escrito como máquina de estados replicada, e serviços reais nascem como protótipo sem plano de disponibilidade. A replicação entra depois, num código que não foi estruturado para ela, muitas vezes sem poder quebrar compatibilidade durante a transição.

O segundo problema era anunciar o resultado. Eleito o primário, os milhares de processos que dependem dele precisam descobrir quem venceu. A ferramenta óbvia, DNS, tem cache baseado em tempo: um TTL curto o suficiente para trocar um servidor morto rápido gera carga absurda. Um job de três mil processos em que todos falam com todos, com TTL de 60s, pediria 150 mil lookups por segundo — e um servidor DNS Xeon de dois núcleos a 2,6 GHz atendia cerca de 50 mil. A variabilidade da carga de DNS já era um problema sério no Google antes do Chubby existir.

a ideia

Em vez de distribuir o consenso, centralize-o num serviço confiável e venda locks. Trocar um servidor comum em servidor eleito passa a custar duas linhas: adquira o lock para virar master, passe o contador de aquisição junto com a RPC de escrita, e faça o destino rejeitar escritas com contador antigo. Programador nenhum precisa aprender Paxos — precisa reconhecer um lock, coisa que ele acha que já sabe usar (e o paper observa que ele geralmente está errado).

Junto vem uma segunda decisão: servir arquivos pequenos. O primário eleito escreve a própria identidade no arquivo do lock, e quem procura por ele lê ali. Isso evita depender de um segundo serviço de nomes e reaproveita a consistência do mesmo protocolo. E há uma inversão de responsabilidade escondida no quorum: uma célula do Chubby usa cinco réplicas, três precisam estar de pé — mas um cliente sozinho, com um único processo vivo, consegue segurar o lock e progredir com segurança. O serviço funciona como eleitorado emprestado.

como funciona

Uma célula tem cinco réplicas em racks distintos. Elas elegem um master por consenso, com promessa de não eleger outro durante o master lease, de alguns segundos. Só o master lê e escreve o banco; escritas viram consenso e são confirmadas quando alcançam a maioria; leituras o master responde sozinho, seguro porque enquanto o lease vale nenhum outro master pode existir.

A interface é um sistema de arquivos podado: árvore estrita, sem link, sem rename entre diretórios, sem tempo de último acesso, permissão só do próprio nó — tudo isso para permitir particionar o namespace por diretório mais tarde. Nós são permanentes ou efêmeros, e o nó efêmero some quando ninguém o mantém aberto, o que serve de sinal de vida. Qualquer nó é um lock reader-writer advisory: segurar o lock F não impede ninguém de ler o arquivo F.

O cliente mantém uma sessão viva por KeepAlives. O master segura a RPC até o lease anterior estar perto de vencer e só então responde com o novo prazo, 12s por padrão, esticável para uns 60s quando ele está sobrecarregado. Eventos e invalidações de cache pegam carona nessa resposta, o que garante que ninguém renove sessão sem confirmar invalidação e faz todo tráfego fluir do cliente para o master. O cliente mantém uma estimativa conservadora do prazo; quando ela vence, ele esvazia o cache e entra em jeopardy por um grace period de 45s, bloqueando as chamadas da aplicação até saber se a sessão sobreviveu. O novo master escolhe um epoch novo, rejeita chamadas com epoch velho, reconstrói sessões e locks do banco e só depois libera as operações.

O cache é write-through, consistente, mantido por invalidação — nunca por atualização, porque protocolo que só atualiza pode mandar update para sempre a um cliente que leu uma vez. O banco começou como Berkeley DB replicado e virou um WAL com snapshot escrito em casa: o código de replicação do Berkeley DB era novo demais para o risco. O snapshot vai para um servidor GFS em outro prédio, para não criar dependência cíclica com uma célula que pode precisar do Chubby para eleger o próprio master.

o que isso custou

O master é único por célula, e a máquina dele é igual à dos clientes. Perto da sobrecarga — tipicamente acima de 90 mil sessões — a latência dispara e sessões caem. Escrita leva 5 a 10 ms a mais pelo log, e até dezenas de segundos se um cliente recém-morto tinha aquele arquivo em cache. O código de fail-over, exercitado raramente, foi descrito pelos próprios autores como fonte rica de bugs interessantes. Em algumas dezenas de anos-célula, dados foram perdidos seis vezes: quatro por bug do banco, duas por erro de operador, nenhuma por hardware — e os erros de operação aconteceram durante upgrades feitos para corrigir os bugs.

Sem quota, um módulo de rastreio de uploads passou a reescrever um arquivo de 1,5 MB inteiro a cada ação de usuário, consumindo mais espaço que todos os outros clientes somados; o limite de 256 kB veio depois, e a migração levou cerca de um ano. Desenvolvedores tratam o serviço como sempre disponível: houve quem derrubasse centenas de máquinas em recuperação de dezenas de minutos ao receber o evento de fail-over. A biblioteca cliente em C++ tem 7 mil linhas e ninguém quis reescrevê-la em Java, então virou mais um servidor de conversão de protocolo. E os KeepAlives tiveram de sair de TCP para UDP, porque o back-off do TCP ignora prazos de nível mais alto e derrubava sessões sob congestionamento.

Duas admissões honestas fecham a conta. O paper diz de saída que não é pesquisa e não propõe algoritmo novo. E o servidor de locks finos que eles projetaram para clientes nunca precisou ser escrito: quem otimiza a aplicação acaba removendo comunicação, e removendo comunicação acaba em lock grosseiro.

onde isso aparece hoje

O Google File System usa um lock do Chubby para nomear o master. O Bigtable o usa três vezes: elege master, deixa o master descobrir os servidores que controla e deixa clientes acharem o master. O MapReduce o usa como ponto de encontro. Nos dois primeiros, o Chubby também guarda a raiz da estrutura de dados distribuída — a metadata pequena de onde tudo o mais pende.

O padrão de embrulhar Paxos num serviço com interface de arquivo, sessões e watches saiu do Google: o ZooKeeper e, mais tarde, o etcd ocupam esse lugar em pilhas abertas, com a mesma divisão entre um quorum pequeno e muitos clientes que só querem saber quem manda agora.

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