A mensagem não sumiu. Foi você que não a viu passar.

No post anterior, falamos sobre como o Kafka garante durabilidade no cluster: replicação, ISR, acks=all. O broker fez a parte dele.

Mesmo assim, os times continuam abrindo chamado: "a mensagem foi perdida".

Quase sempre, não foi.


Perda física vs perda lógica

Perda física: a mensagem não existe mais no cluster. Retention expirou, tópico deletado, falha sem replicação. Com configuração correta, isso é raro.

Perda lógica: a mensagem está no tópico, mas o consumer não processou corretamente, ou achou que processou, mas não persistiu o efeito.

A mensagem está lá. O problema está no consumer.


Cenário real

Serviço de transferências financeiras (TED/PIX):

O consumer lê a mensagem e chama a API do banco liquidante.

A API demora 8s. O auto-commit dispara (padrão: 5s).

Offset commitado. O Kafka entende que foi processado.

A chamada retorna erro. O consumer tenta reprocessar.

Tarde demais. O offset já avançou.

Para o Kafka: tudo certo. Para o cliente: dinheiro debitado, transferência não efetivada.


As 4 causas mais comuns

  1. Auto-commit antes de processar: o offset avança antes da lógica de negócio terminar.
  2. Persistência após o commit: o consumer commita, tenta salvar no banco, a aplicação cai. O efeito nunca aconteceu.
  3. Falha silenciosa: uma exceção é engolida, o offset avança. A mensagem "some" sem deixar rastro.
  4. max.poll.records alto + processamento lento: o consumer é expulso do grupo no meio do processamento. Mensagens podem ser reprocessadas ou "saltadas" do ponto de vista do seu efeito.

Como evitar

  • Desligue auto-commit: enable.auto.commit=false
  • Commit manual após persistir (ordem sagrada): processar -> persistir -> commitar
  • DLT (Dead Letter Topic) para falhas explícitas: essencial para auditoria (principalmente em financeiro)
  • Calibre max.poll.interval.ms para o tempo real de processamento
  • Lag zerado não significa "processado com sucesso": significa só que o offset avançou

Regra de ouro

O Kafka garante que a mensagem chegou ao broker. Quem garante que ela foi processada é o seu código.

Seu time já tem idempotência e DLT configurados? Comenta aqui.