Pular para o conteúdo

Design clássico · Sênior

Fila de mensagens distribuída (estilo Kafka)

Projeto de entrevista clássico. Pontos centrais: storage engines (LSM).

16 min de leitura · Conteúdo revisado em 22 de outubro de 2026

Resposta curta

Projeto de entrevista clássico. Pontos centrais: storage engines (LSM). Uma fila de mensagens separa quem produz de quem consome. O produtor entrega a mensagem e segue; o consumidor busca no seu ritmo. Esse buffer no meio é o que permite que dois sistemas evoluam, escalem e falhem de forma independente.

01 · CONTEXTO E REQUISITOS

Por que uma fila distribuída existe

Uma fila de mensagens separa quem produz de quem consome. O produtor entrega a mensagem e segue; o consumidor busca no seu ritmo. Esse buffer no meio é o que permite que dois sistemas evoluam, escalem e falhem de forma independente.

O desenho do Kafka partiu de requisitos bem concretos: alta vazão para fluxos de eventos de grande volume, como agregação de logs; tolerância a grandes backlogs, para cargas periódicas vindas de sistemas offline; e entrega de baixa latência para usos de mensageria tradicional.

  1. O produtor entrega a mensagem à fila e segue em frente; ele não espera o processamento.

    Diagrama da arquitetura: Fila simples entre produtor e consumidor
    CPProdutor
    QFila de mensagens
    CPConsumidor
  2. A fila guarda as mensagens na ordem de chegada. É esse buffer que absorve picos e backlog.

    Diagrama da arquitetura: Fila simples entre produtor e consumidor
    CPProdutor
    QFila de mensagensbuffer
    CPConsumidor
  3. O consumidor busca mensagens quando tem capacidade; se atrasar, a fila acumula em vez de perder.

    Diagrama da arquitetura: Fila simples entre produtor e consumidor
    CPProdutor
    QFila de mensagens
    CPConsumidor

02 · O LOG

Um log em disco, só com acréscimos

A ideia central é guardar a fila como um log: as mensagens são sempre acrescentadas no fim de um arquivo. A documentação do Kafka descreve que uma fila persistente pode ser construída sobre leituras e acréscimos simples a arquivos, e que nessa estrutura todas as operações são O(1) e leituras não bloqueiam escritas.

Disco parece lento por causa do acesso aleatório. A documentação mede a diferença: no arranjo que ela cita, escrita linear chega a cerca de 600 MB/s, contra cerca de 100 kB/s de escrita aleatória, uma diferença de mais de 6000 vezes. Por isso um disco bem usado pode ser tão rápido quanto a rede, e o Kafka depende fortemente do sistema de arquivos.

CritérioEscrita linear (acréscimo)Escrita aleatória
Vazão medida na documentaçãoCerca de 600 MB/sCerca de 100 kB/s
Operação sobre o logAcrescentar no fim, em tempo constanteNão se aplica ao log

Dois truques completam o ganho. Primeiro, o agrupamento em lotes: o produtor reúne mensagens, comprime o lote e o servidor o anexa de uma vez, o que transforma rajadas de escritas aleatórias em escritas lineares. Segundo, o cache de páginas do sistema operacional: com consumidores em dia, as leituras saem do cache e o disco quase não é lido.

03 · PARTIÇÕES E CONSUMIDORES

Escalar a leitura sem perder a ordem

Um único log não escala além de uma máquina. A saída é dividir o tópico em partições, cada uma um log independente. O cliente produtor escolhe a partição, ao acaso ou por uma função semântica sobre a chave, e a ordem total existe dentro de cada partição, não entre elas.

Os consumidores se organizam em grupos. Dentro de um grupo, cada partição é lida por exatamente um consumidor por vez; assim, o paralelismo máximo de um grupo é limitado pelo número de partições.

  1. O cliente produtor decide em qual partição cada mensagem entra, ao acaso ou por uma função sobre uma chave.

    Diagrama da arquitetura: Partições e grupo de consumidores
    CPProdutor
    QPartição Anovo
    QPartição Bnovo
    QPartição Cnovo
    CPConsumidor X
    CPConsumidor Y
  2. Cada partição é um log ordenado. A ordem existe dentro da partição, não entre partições.

    Diagrama da arquitetura: Partições e grupo de consumidores
    CPProdutor
    QPartição A
    QPartição Bordem local
    QPartição C
    CPConsumidor X
    CPConsumidor Y
  3. Dentro do grupo, cada partição tem um único consumidor por vez; um consumidor pode ficar com várias partições.

    Diagrama da arquitetura: Partições e grupo de consumidores
    CPProdutor
    QPartição A
    QPartição B
    QPartição C
    CPConsumidor X
    CPConsumidor Y
  4. O consumidor guarda só um inteiro por partição, o offset. Atrasar é inofensivo, e voltar a um offset antigo permite reprocessar.

    Diagrama da arquitetura: Partições e grupo de consumidores
    CPProdutor
    QPartição Aoffset
    QPartição B
    QPartição C
    CPConsumidor Xatrasado
    CPConsumidor Y

A posição de leitura é só um inteiro por partição, o offset da próxima mensagem. O consumidor informa o offset a cada requisição e recebe um trecho do log a partir dali. Como ele puxa os dados, um consumidor lento apenas atrasa e alcança depois, e pode também voltar a um offset antigo e reconsumir.

04 · REPLICAÇÃO E FALHAS

Sobreviver à queda de um broker

Cada partição é replicada em vários brokers, e a unidade de replicação é a própria partição. Toda escrita vai ao líder; os seguidores puxam o log do líder e o aplicam ao seu. O Kafka assume replicação por padrão: um tópico sem réplicas é só um tópico com fator de replicação um.

O líder acompanha o conjunto de réplicas em sincronia (ISR). Uma mensagem só é considerada confirmada quando todas as réplicas desse conjunto a aplicaram. Com esse modelo e f+1 réplicas, o tópico tolera f falhas sem perder mensagens confirmadas; um quórum de maioria exigiria três cópias para uma falha e cinco para duas.

  1. O produtor escreve direto no líder da partição, sem camada de roteamento no meio.

    Diagrama da arquitetura: Partição replicada com líder e seguidores
    CPProdutor
    QBroker líderlíder
    QSeguidor em sincronia
    QSeguidor atrasado
    CPControlador
    CPConsumidor
  2. Os seguidores puxam o log do líder e aplicam as mensagens ao próprio log.

    Diagrama da arquitetura: Partição replicada com líder e seguidores
    CPProdutor
    QBroker líder
    QSeguidor em sincronia
    QSeguidor atrasado
    CPControlador
    CPConsumidor
  3. Só as réplicas em sincronia contam para confirmar a mensagem. Um seguidor que atrasa demais pode ser removido desse conjunto.

    Diagrama da arquitetura: Partição replicada com líder e seguidores
    CPProdutor
    QBroker líder
    QSeguidor em sincroniaem sincronia
    QSeguidor atrasadofora do ISR
    CPControlador
    CPConsumidor
  4. O líder cai. Escritas nessa partição ficam sem destino até haver um novo líder.

    Diagrama da arquitetura: Partição replicada com líder e seguidores
    CPProdutor
    QBroker líderfora do ar
    QSeguidor em sincronia
    QSeguidor atrasado
    CPControlador
    CPConsumidor
  5. O controlador percebe a perda da sessão do broker, e um seguidor do conjunto em sincronia é eleito. Ele já tem todas as mensagens confirmadas.

    Diagrama da arquitetura: Partição replicada com líder e seguidores
    CPProdutor
    QBroker líder
    QSeguidor em sincronianovo líder
    QSeguidor atrasado
    CPControlador
    CPConsumidor
  6. Produtor e consumidor consultam os metadados, descobrem o novo líder e retomam o trabalho.

    Diagrama da arquitetura: Partição replicada com líder e seguidores
    CPProdutor
    QBroker líder
    QSeguidor em sincronialíder
    QSeguidor atrasado
    CPControlador
    CPConsumidor
CritérioSó eleição entre réplicas em sincroniaEleição não limpa permitida
Se todas as réplicas caemA partição fica indisponível até o último líder voltarAceita assumir com uma réplica fora do conjunto
PrioridadeDurabilidade e consistênciaDisponibilidade, para casos em que ficar no ar é preferível à consistência

05 · ENTREGA E RETENÇÃO

Duplicata, perda e o que guardar

Confirmar entrega esbarra num dilema. Se o broker marcar a mensagem como consumida ao entregá-la e o consumidor falhar, a mensagem se perde. Se o consumidor processar e falhar antes de confirmar, a mensagem é consumida duas vezes. Do lado do produtor, reenviar após um erro pode gravar a mensagem de novo.

SemânticaComo se obtémRisco
No máximo uma vezDesligar retentativas no produtor e confirmar o offset antes de processarMensagem perdida
Pelo menos uma vezReenviar até confirmar e confirmar o offset só depois de processarMensagem duplicada
Sem duplicatas no logProdutor idempotente, que impede entradas duplicadas ao reenviarNão cobre sozinho o processamento do consumidor

O padrão do Kafka é entregar pelo menos uma vez; no máximo uma vez é uma opção. Por isso o consumidor precisa tolerar repetição: o desenho clássico é torná-lo uma operação idempotente, por exemplo descartando um identificador já visto.

Por fim, guardar tudo para sempre não cabe. A retenção simples descarta dados antigos depois de um período fixo ou quando o log atinge um tamanho limite. Quando importa só o estado mais recente de cada chave, a compactação de log mantém ao menos o último valor de cada chave dentro de uma partição.

Perguntas frequentes

O que é Fila de mensagens distribuída (estilo Kafka)?

Projeto de entrevista clássico. Pontos centrais: storage engines (LSM).

O que o design de Fila de mensagens distribuída (estilo Kafka) cobre?

Ele está organizado nestas seções: Por que uma fila distribuída existe, Um log em disco, só com acréscimos, Escalar a leitura sem perder a ordem, Sobreviver à queda de um broker e Duplicata, perda e o que guardar.

Quanto tempo leva Fila de mensagens distribuída (estilo Kafka) e qual é o nível?

Leva cerca de 16 minutos para ler e tem nível Sênior.

Agora projete você mesmo

Rode este caso como uma entrevista na escola de System Design: você toma as decisões, o tutor as questiona e você vê a nota do seu desenho.