Arquitetura Kafka Explicada: Componentes Principais e Seus Papéis

Explore os blocos de construção fundamentais da arquitetura de streaming de eventos distribuídos do Apache Kafka. Este guia explica claramente os papéis dos Brokers Kafka, Tópicos, Partições, Produtores, Consumidores e o papel de coordenação do ZooKeeper. Aprenda como esses componentes interagem para garantir processamento e armazenamento de dados de alta vazão e tolerantes a falhas, conhecimento essencial para qualquer implementação Kafka.

Arquitetura Kafka Explicada: Componentes Principais e Seus Papéis

A arquitetura Kafka pode parecer confusa no início porque o mesmo sistema lida com armazenamento, streaming, replicação e progresso do consumidor. Depois que você separa as partes principais, o modelo fica muito mais fácil: produtores escrevem registros em partições de tópicos, brokers armazenam essas partições e consumidores leem registros por offset.

Este guia explica os componentes principais do Kafka e como eles trabalham juntos em um cluster real.

Brokers: Os Servidores Kafka

Um cluster Kafka é composto por um ou mais brokers. Um broker é um servidor Kafka que armazena dados de partição e lida com requisições de clientes, tanto produtores quanto consumidores.

Quando um produtor envia um registro, ele escreve no broker que atualmente lidera a partição de destino. Quando um consumidor lê registros, ele os busca do broker que serve aquela partição. Em configurações normais, cada broker lida com muitas partições de muitos tópicos.

Adicionar brokers pode aumentar a capacidade de armazenamento e distribuir o tráfego, mas não corrige automaticamente todos os gargalos. Você também precisa de partições suficientes, posicionamento balanceado de réplicas, discos saudáveis e capacidade de rede.

Tópicos: Fluxos Nomeados de Registros

Um tópico é um fluxo nomeado de registros, como pedidos, pagamentos ou atividade_usuario. Produtores escrevem em tópicos e consumidores se inscrevem em tópicos.

Um tópico é dividido em partições. Cada partição é um log ordenado e somente de acréscimo. Kafka garante a ordem dos registros dentro de uma única partição, não em todo o tópico.

Esse detalhe é importante. Se todos os eventos de um cliente devem ser processados em ordem, use uma chave estável como id_cliente. O particionador padrão do Kafka usa a chave para escolher uma partição, então registros com a mesma chave normalmente vão para a mesma partição.

Partições e Offsets

Cada registro em uma partição recebe um offset. O offset é um número que identifica a posição do registro naquela partição.

Por exemplo, um tópico chamado pedidos com três partições pode ser assim:

pedidos-0: offset 0, offset 1, offset 2
pedidos-1: offset 0, offset 1
pedidos-2: offset 0, offset 1, offset 2, offset 3

Offsets são significativos apenas dentro de sua própria partição. O offset 3 em pedidos-2 não está relacionado ao offset 3 em outra partição.

Partições fornecem paralelismo ao Kafka. Mais partições permitem que mais consumidores no mesmo grupo de consumidores trabalhem ao mesmo tempo, até um consumidor ativo por partição dentro desse grupo.

Replicação e Líderes

Kafka usa replicação para manter os dados disponíveis quando um broker falha. Cada partição pode ter múltiplas réplicas em diferentes brokers.

Uma réplica é o líder. Produtores e consumidores normalmente falam com o líder daquela partição. As outras réplicas são seguidoras. Seguidores copiam dados do líder e ficam prontos para assumir se o líder falhar.

O fator de replicação controla quantas cópias o Kafka mantém. Um fator de replicação de 3 significa que o Kafka armazena três cópias de cada partição em três brokers, quando brokers suficientes estão disponíveis.

Você pode criar um tópico assim:

kafka-topics.sh --create \
  --topic atividade_usuario \
  --bootstrap-server localhost:9092 \
  --partitions 3 \
  --replication-factor 3

Esse comando requer um cluster com pelo menos três brokers. Em uma configuração local de um único broker, use um fator de replicação de 1.

Produtores: Aplicações Que Escrevem Eventos

Produtores enviam registros para tópicos Kafka. Um registro pode incluir uma chave, valor, timestamp e cabeçalhos.

O produtor primeiro pergunta ao cluster por metadados para saber qual broker lidera cada partição. Então ele envia registros diretamente para o broker correto.

A confiabilidade do produtor depende fortemente de configurações como:

Configuração O que afeta
acks Quantas confirmações do broker são necessárias antes que uma escrita seja considerada bem-sucedida
retries Se o produtor tenta novamente falhas transitórias
enable.idempotence Ajuda a evitar duplicatas causadas por novas tentativas do produtor
compression.type Reduz o uso de rede e disco para muitas cargas de trabalho

Para dados importantes, acks=all é comum porque o líder espera pelas réplicas em sincronia antes de confirmar a escrita. O comportamento exato também depende de configurações do broker, como min.insync.replicas.

Consumidores e Grupos de Consumidores

Consumidores leem registros de tópicos. A maioria dos consumidores em produção executa dentro de um grupo de consumidores.

Dentro de um grupo de consumidores, o Kafka atribui cada partição a apenas um consumidor ativo por vez. É assim que o Kafka permite escalar o processamento enquanto preserva a ordem dentro de cada partição.

Por exemplo, se pedidos tem três partições e seu serviço tem três consumidores no mesmo grupo, cada consumidor pode processar uma partição. Se você adicionar um quarto consumidor ao mesmo grupo, um consumidor ficará ocioso porque há apenas três partições para atribuir.

Grupos de consumidores diferentes obtêm leituras independentes. Seu serviço de faturamento e serviço de análise podem ambos ler o tópico pedidos sem roubar registros um do outro.

Offsets e Progresso do Consumidor

Consumidores acompanham o progresso confirmando offsets. Kafka armazena offsets confirmados para grupos de consumidores em um tópico interno chamado __consumer_offsets.

Se um consumidor falhar e reiniciar, ele usa o offset confirmado para retomar. O momento das confirmações afeta o comportamento do processamento:

Momento da confirmação Resultado possível
Confirmar antes do processamento terminar Uma falha pode pular registros
Confirmar após o processamento terminar Uma falha pode reprocessar registros

Muitos sistemas escolhem processamento pelo menos uma vez: processar o registro, depois confirmar o offset. Isso pode criar duplicatas após uma falha, então as escritas downstream devem ser idempotentes quando possível.

Metadados do Cluster: ZooKeeper e KRaft

Clusters Kafka mais antigos usam Apache ZooKeeper para gerenciar metadados do cluster e eleição do controlador. Muitas instalações existentes ainda funcionam assim.

Implantações Kafka mais novas podem usar o modo KRaft, o quórum de metadados embutido do Kafka. Em clusters KRaft, o Kafka não depende mais do ZooKeeper para gerenciamento de metadados.

Ao ler tutoriais Kafka mais antigos, verifique se eles assumem ZooKeeper ou KRaft. Comandos, arquivos de configuração e etapas operacionais podem diferir.

Como um Registro se Move Através do Kafka

Um fluxo típico de escrita e leitura é assim:

  1. Um produtor se conecta a um broker de bootstrap e busca metadados.
  2. O produtor escolhe uma partição com base na chave do registro ou estratégia de particionamento.
  3. O produtor envia o registro para o broker líder daquela partição.
  4. O líder anexa o registro ao seu log e os seguidores o replicam.
  5. O líder confirma a escrita com base na configuração acks do produtor.
  6. Um consumidor consulta a partição e recebe registros a partir do seu offset atual.
  7. O consumidor processa registros e confirma offsets para seu grupo de consumidores.

Este fluxo é a razão pela qual o Kafka pode suportar tanto processamento em tempo real quanto reprodução. Consumidores não removem registros quando os leem.

Retenção: Kafka Mantém Dados por Política

Kafka não é uma fila tradicional onde uma mensagem desaparece assim que um consumidor a lê. Kafka mantém registros com base em configurações de retenção.

Configurações comuns de tópico incluem:

retention.ms=604800000
retention.bytes=10737418240

retention.ms controla a retenção baseada em tempo. retention.bytes controla a retenção baseada em tamanho. A limpeza real também depende de configurações de segmento e configuração do broker.

Alguns tópicos usam compactação de log em vez de, ou junto com, retenção baseada em exclusão. A compactação mantém o valor mais recente para cada chave, o que é útil para tópicos com estado, como perfis de usuário ou mudanças de configuração.

O Que Lembrar

A arquitetura do Kafka é construída em torno de logs particionados. Brokers armazenam partições, produtores escrevem em líderes de partição, consumidores leem por offset e grupos de consumidores dividem o trabalho entre partições.

Ao projetar um tópico Kafka, pense sobre ordenação, número de partições, fator de replicação, retenção e comportamento do grupo de consumidores juntos. Essas escolhas moldam como seu sistema escala, se recupera de falhas e reproduz eventos antigos.