Quando o lag sobe, a reação mais comum é olhar para broker, CPU, disco ou rede.

Só que, muitas vezes, o cluster está saudável.

No post anterior, falamos que lag alto é sintoma, não diagnóstico. Um dos motivos mais traiçoeiros para isso é a hot partition.


Conceito: o que é uma hot partition?

Hot partition é quando uma partition recebe muito mais mensagens do que as outras.

Na prática, isso cria um gargalo silencioso.

O tópico pode ter várias partitions. O consumer group pode ter várias instâncias. O cluster pode estar estável.

Mesmo assim, o throughput real fica limitado pela partition que concentrou a maior parte da carga.

Esse problema normalmente nasce de duas coisas:

  • escolha ruim de key
  • distribuição desigual do tráfego entre os valores dessa key

Em outras palavras: o Kafka está pronto para paralelizar, mas a forma como os eventos foram distribuídos impede que esse paralelismo aconteça de verdade.


Por que isso acontece

As causas mais comuns são bem menos exóticas do que parecem:

  1. Key com baixa cardinalidade: Usar algo como status, tipoEvento ou regiao parece simples, mas poucos valores possíveis significam poucas rotas reais de distribuição.

  2. Key de negócio com tráfego concentrado: customerId, sellerId ou accountId podem fazer sentido para preservar ordem. O problema é quando poucos IDs concentram volume muito acima da média.

  3. Crescimento de volume sem revisão da estratégia: A key funcionava bem no início, mas o sistema cresceu, alguns clientes passaram a movimentar muito mais eventos e a distribuição deixou de ser saudável.

  4. Ordem tratada como requisito absoluto: Às vezes a key é escolhida para preservar ordem por entidade, mesmo quando o processamento não exige isso em todos os casos. O custo aparece depois, em forma de gargalo.


Cenário real

Imagine um tópico de pedidos com 12 partitions.

O producer usa customerId como key. A decisão parece correta: eventos do mesmo cliente ficam na mesma partition e a ordem é preservada.

Agora entra o detalhe que quase sempre aparece só em produção:

3 clientes enterprise geram 70% do volume do tópico.

Resultado:

  • quase todas as mensagens desses clientes caem sempre nas mesmas partitions
  • essas partitions acumulam backlog
  • as demais partitions ficam com pouco trabalho
  • o consumer group parece bem dimensionado, mas o throughput total fica preso nos mesmos pontos de estrangulamento

Outro exemplo comum é usar status como key:

  • PENDING
  • PROCESSING
  • FAILED

A cardinalidade é tão baixa que a concentração de carga deixa de ser risco e vira consequência natural.


Como detectar o problema

O erro mais comum aqui é olhar apenas o lag total do tópico.

Lag agregado ajuda a perceber atraso. Não ajuda a entender distribuição.

Para identificar hot partition, o ideal é observar o comportamento por partition.

Sinais fortes:

  • lag alto concentrado em poucas partitions
  • outras partitions com lag baixo ou zerado
  • alguns consumers muito mais ocupados do que outros no mesmo group
  • throughput abaixo do esperado mesmo com brokers saudáveis
  • mais pods sem ganho proporcional de consumo

Perguntas úteis durante a investigação:

  • O lag está espalhado entre todas as partitions ou concentrado em 1 ou 2?
  • As partitions com maior lag também recebem mais mensagens por segundo?
  • Existe alguma key dominando grande parte do volume?
  • O número de consumers já está próximo do número de partitions e, ainda assim, o atraso continua?

Essa distinção é importante:

  • se todas as partitions acumulam lag, o problema pode ser capacidade insuficiente do consumer
  • se o lag está concentrado em poucas partitions, a suspeita de hot partition fica muito mais forte

Hot partition e consumer lento podem coexistir. Mas são problemas diferentes e exigem decisões diferentes.


Por que mais consumers nem sempre resolvem

Quando o lag sobe, aumentar a quantidade de consumers parece a resposta mais óbvia.

Nem sempre é.

No Kafka, o paralelismo é limitado pelo número de partitions. Mas, na prática, ele também é limitado por como a carga está distribuída entre elas.

Se 80% das mensagens caem em 2 partitions, são essas 2 partitions que definem o ritmo de consumo.

Adicionar mais consumers só ajuda quando existe trabalho distribuído para eles processarem.

Se a carga continua concentrada, você escala o grupo e continua esperando pelas mesmas partitions quentes.

Essa é uma dúvida comum: "não daria para colocar mais threads para consumir a partition sobrecarregada?"

Em um mesmo consumer group, não.

Uma partition só pode ter um consumer ativo por vez. Isso significa que o paralelismo no Kafka acontece entre partitions, não dentro da mesma partition.

Se o gargalo está concentrado em uma partition quente, mais threads no grupo não destravam esse ponto específico.

O que até pode existir é paralelizar o processamento depois da leitura, dentro da aplicação. Mas isso já é outra estratégia, com custo real de complexidade: controle de ordem, commit, retry e tratamento de falhas ficam muito mais delicados.

Ou seja: não é "mais thread no Kafka". É uma mudança no desenho do processamento.


Como pensar uma boa key

A melhor key não é necessariamente a mais intuitiva do ponto de vista de negócio.

Antes de escolher, vale responder:

  • Eu realmente preciso de ordem por essa entidade?
  • Essa key tem cardinalidade suficiente?
  • O tráfego tende a se distribuir bem entre os valores possíveis?
  • Existem poucos clientes, contas ou parceiros que podem concentrar volume?
  • Estou otimizando para semântica de negócio, para distribuição, ou tentando fazer as duas coisas ao mesmo tempo?

Uma boa key costuma ter estas características:

  • cardinalidade razoável
  • distribuição previsivelmente equilibrada
  • alinhamento com a necessidade real de ordenação
  • comportamento sustentável quando o volume crescer

Alguns alertas práticos:

  • chave de negócio nem sempre é boa chave de particionamento
  • poucos valores possíveis quase sempre indicam risco
  • uma key que funciona em baixo volume pode virar gargalo em escala
  • preservar ordem demais pode custar throughput demais

Estratégias para evitar ou reduzir hot partitions

Não existe fórmula mágica, mas algumas decisões ajudam bastante:

  • revisar a key com base em distribuição real, não só em semântica
  • medir cardinalidade e concentração antes de consolidar a estratégia
  • evitar atributos com poucos valores possíveis como chave principal
  • separar, quando possível, necessidade de ordenação e necessidade de balanceamento
  • reavaliar o número de partitions junto com a estratégia de distribuição

Vale um cuidado importante:

Aumentar o número de partitions não corrige sozinho uma key ruim.

Se a lógica de particionamento continua concentrando tráfego nas mesmas chaves, você apenas aumenta o espaço disponível para uma distribuição que continua desigual.

Em alguns cenários, compor a key com mais de um atributo pode melhorar o balanceamento. Em outros, a melhor decisão é aceitar menos ordenação por entidade em troca de mais capacidade real de processamento.

Arquitetura é tradeoff. O erro é fingir que esse tradeoff não existe.


Checklist rápido de investigação

Antes de culpar o broker ou escalar o consumo, vale passar por estas perguntas:

  • O lag está em todas as partitions ou só em algumas?
  • As partitions com maior atraso também concentram mais produção?
  • Existe concentração de volume em poucas keys?
  • O consumer group está escalado, mas o throughput real continua baixo?
  • A escolha da key foi validada com padrão real de tráfego ou apenas com regra de negócio?

Regra de ouro

Hot partition é um gargalo arquitetural, não um azar operacional.

Quando a distribuição da carga é ruim, o Kafka pode continuar saudável e, ainda assim, o paralelismo real praticamente desaparecer.

Particionamento não é detalhe de implementação. É decisão de arquitetura.

Seu time hoje conhece a distribuição real das keys dos tópicos mais críticos, ou só descobrimos isso quando o lag explode?