Coordenação sem um centro

Prévia grátis 5 min de leitura

Um protocolo de fofoca é o jeito como um grupo grande de máquinas chega a um acordo sobre fatos a respeito de si mesmo quando nenhuma máquina está no comando. Para entender, comece olhando o que esta aplicação faz no lugar disso.

O que esta aplicação faz no lugar disso

Aqui há três mecanismos de coordenação, e os três são o mesmo mecanismo.

# config/queue.yml (resumido)
dispatchers:
  - polling_interval: 1
    batch_size: 500
workers:
  - queues: "default"
    threads: 3
    polling_interval: 0.1
  # mais dois grupos de workers, cada um com a própria fila e intervalo
# config/cable.yml (produção)
polling_interval: 0.1.seconds
message_retention: 1.day
# config/deploy.yml (seção proxy)
healthcheck:
  path: /up
  interval: 5

Um despachante de jobs pergunta ao banco a cada segundo. Um grupo de workers pergunta mais ou menos a cada décimo de segundo. O ouvinte do cable em cada processo do servidor pergunta a cada décimo de segundo, tenha ele quantos assinantes de WebSocket tiver. E, durante um deploy, o proxy pergunta ao contêiner novo a cada cinco segundos até ele responder.

Ninguém avisa ninguém de nada. Cada participante pergunta sem parar a uma única autoridade compartilhada, o banco ou a própria aplicação, e essa autoridade é todo o mecanismo de coordenação.

Por que isso funciona aqui

Funciona porque a autoridade existe e é alcançável: um nó PostgreSQL, dois processos Puma, um proxy.

Neste tamanho, consultar um armazenamento compartilhado é o projeto certo, e vale dizer isso com clareza em vez de tratar como limitação. É simples, não tem modos de falha próprios além dos do armazenamento e custa uma consulta por intervalo por participante.

Esse último ponto é onde a coisa para de funcionar. Custo por participante vezes o número de participantes é a propriedade de escala, e ela vai bem com três e é impossível com três mil.

flowchart TB
  subgraph "esta aplicação"
    W1["worker"] --> DB[("banco compartilhado")]
    W2["despachante"] --> DB
    C1["ouvinte do cable"] --> DB
    P["proxy, durante um deploy"] --> APP["/up"]
  end
  DB --> N["uma autoridade. todos perguntam a ela. ninguém conta nada"]

Quando não há autoridade

A fofoca parte desta premissa: não existe um armazenamento compartilhado que todo nó alcance, ou alcançá-lo custa mais do que a coordenação vale.

Isso acontece por dois motivos. Um é a escala: mil nós consultando um coordenador fazem dele o gargalo e o ponto único de falha. O outro é a geografia: nós em três continentes não conseguem todos alcançar um armazenamento a baixo custo, como o curso de nível Sênior "Arquitetura: banco de dados multi-região" mediu, com cerca de 200ms por ida e volta entre São Paulo e Frankfurt.

Então os nós conversam entre si. Cada nó, de tempos em tempos, escolhe alguns pares ao acaso e troca o que sabe: quem está vivo, quem entrou, quem saiu e qual versão da lista de membros ele tem.

Ninguém tem o quadro completo em nenhum momento, e todo mundo chega a ele rápido.

A troca que se faz

Autoridade central (esta aplicação) Fofoca
Quem sabe a verdade Um armazenamento Ninguém, depois todos
Custo por nó Uma consulta por intervalo Algumas mensagens por intervalo
Custo no centro Cresce com o número de nós Não existe centro
Falha do centro Tudo para Não se aplica
Atualidade Tão atual quanto o intervalo Converge em O(log N) rodadas
Complexidade Quase nenhuma Considerável

Leia a última linha. A fofoca não é melhor. É o que você usa quando a linha de cima ficou inaceitável.

Essa linha só fica inaceitável numa escala de que esta aplicação está muito longe. É esse o enquadramento justo deste curso: você está aprendendo o formato de uma solução para um problema que precisa saber reconhecer, e não inventar.

A única coisa para levar mesmo neste tamanho

Intervalos de consulta são um orçamento de coordenação, e as pessoas costumam escolhê-los sem ter um.

O polling_interval: 0.1 no Solid Cable significa que o ouvinte de cada processo do servidor faz dez consultas por segundo, para sempre, aconteça algo ou não. Com WEB_CONCURRENCY: 2, são vinte consultas por segundo: uma carga conhecida e limitada. O número que importa é consultas por segundo por participante vezes o número de participantes. Vale calcular uma vez, porque a escala em que isso deixa de ir bem chega sem nenhuma mudança no código.

Pontos-chave

  • Esta aplicação coordena consultando uma autoridade compartilhada: o despachante a cada 1s, workers e ouvintes do cable a cada 0,1s, e a checagem de saúde do deploy a cada 5s.
  • Neste tamanho, consultar um armazenamento compartilhado é o projeto certo, e custa uma consulta por intervalo por participante.
  • A premissa da fofoca é que não existe autoridade compartilhada alcançável, por causa da escala ou da geografia.
  • Na fofoca, os nós trocam o que sabem com alguns pares aleatórios. Ninguém tem o quadro todo, e todos convergem.
  • Intervalos de consulta são um orçamento de coordenação. Calcule consultas por segundo vezes participantes uma vez, porque a escala chega sem o código mudar.
Aula 1 de 7 · grátis

Continue com a aula 2

Como a fofoca se espalha

O laço de quatro passos da fofoca, a tolerância a falhas dos pares aleatórios e a convergência em log N rodadas.

Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.

Digite para buscar...