Em uma arquitetura distribuída, as comunicações entre sistemas formam a base de toda a infraestrutura. O desempenho, a escalabilidade e a confiabilidade da infraestrutura dependem muito de como eventos/mensagens/dados são trocados e persistidos.
Kafka e NATS são duas ferramentas populares para manipulação de streaming e mensagens. Elas têm arquiteturas diferentes e características de desempenho distintas. Elas são adequadas para casos de uso específicos. Neste artigo, compararemos as características do NATS com o Kafka e explicaremos os casos de uso que abordei no trabalho.
1. Arquitetura e Complexidade
NATS
A infraestrutura do NATS tem dois componentes principais:
NATS Core
O NATS Core é a estrutura base de mensagens. Isso suporta Publish-Subscribe (permite que mensagens sejam transmitidas para vários assinantes), Request-Reply (habilita comunicação síncrona) e Grupos de Fila (facilita o balanceamento de carga entre vários assinantes dentro de um grupo).
Isso é projetado para simplicidade, baixa latência, alto desempenho e escalabilidade. Ele se destaca em cenários que exigem baixa latência e alta taxa de transferência. No entanto, o NATS Core sozinho oferece apenas entrega não garantida, o que significa que as mensagens são entregues apenas a assinantes ativos. Os dados serão perdidos se os assinantes estiverem offline. O NATS Core é uma boa opção quando velocidade e escala têm prioridade sobre durabilidade.
JetStream
JetStream traz capacidades de persistência ao topo do Core NATS. Isso ajudou a fornecer durabilidade e confiabilidade às mensagens. Permite que mensagens ou eventos sejam persistidos (disco ou memória) e reproduzidos. Mensagens persistidas podem ser reproduzidas para assinantes novos ou em recuperação. Com JetStream, os usuários obtêm recursos adicionais:
- Retenção de stream: Por quanto tempo as mensagens são retidas. Pode ser baseado em tamanho, tempo ou limites do consumidor.
- Durabilidade do consumidor: Permitindo que os consumidores retomem de onde pararam.
- Reconhecimento de mensagem: Isso garante a confiabilidade da entrega.
JetStream adiciona uma camada de complexidade ao Core NATS. No entanto, isso traz o importante recurso de suportar os casos de uso de entrega garantida, persistência e capacidade de reprodução.
Kafka
O Kafka é um sistema de mensagens distribuído construído com base em uma arquitetura de corretor baseada em log. Os dados no Kafka são organizados em Tópicos e podem ter várias partições. Os consumidores estão conectados a essas partições. Essa arquitetura permite que o Kafka paralelize o consumo de mensagens para um único tópico. Os dados são anexados a um tópico/partições sequencialmente. O Kafka garante a ordem em uma partição. Em um cluster Kafka, pode haver muitos corretores, cada um gerenciando uma lista de tópicos e partições. Para alcançar alta disponibilidade e evitar a perda de dados, o Kafka depende de um fator de replicação, onde as partições são replicadas em vários corretores do Kafka. Como você pode ver, existem vários componentes que devem ser gerenciados para alcançar alta taxa de transferência, tolerância a falhas, retenção de dados e escalabilidade horizontal. Isso aumenta a complexidade arquitetural do Kafka.
2. Alta Disponibilidade e Desempenho
NATS
Todos os nós em um cluster estão interconectados em uma malha, e o cliente pode se conectar a qualquer nó. Essa configuração evita um único ponto de falha. Se um nó falhar, o cliente é conectado automaticamente aos outros nós sem intervenção manual. Isso é chamado de auto-recuperação no NATS. Um nó habilitado para JetStream distribui os fluxos entre todos os nós. Os fluxos são altamente gerenciados e balanceados entre os nós habilitados para JetStream dentro de um cluster de malha.
O JetStream também suporta espelhamento de dados em vários clusters ou nós. No JetStream, líderes são eleitos por fluxo. A replicação de cada fluxo pode ser configurada. Todas essas coisas garantem durabilidade e disponibilidade no NATS.
Kafka
A alta disponibilidade do Kafka é baseada na replicação. Cada tópico pode ter uma ou mais partições. Cada partição é replicada entre os Brokers do Kafka. Isso garante a redundância e a disponibilidade dos dados. O Kafka segue um mecanismo de replicação Leader-Follower. Um líder cuida das leituras e gravações. E o seguidor trabalha na replicação dos dados.
O Kafka mantém algo chamado ISR (In Sync Replicas) para cada partição. Se o líder falhar, um dos ISRs se torna o líder. Para gerenciamento de metadados do cluster e eleição de líderes, o Kafka depende do Zookeeper (KRaft nas versões mais recentes).
Performance and Scalability
|
||
---|---|---|
Recurso
|
NATS
|
Kafka
|
Taxa de Transferência
|
Alta ou baixa latência. Otimizado para mensagens pequenas
|
Otimizado para alta taxa de transferência e mensagens grandes
|
Escalabilidade
|
Escalável horizontalmente com clustering
|
Escalável horizontalmente com particionamento
|
Latência
|
Menos de um milissegundo
|
Milissegundos
|
Recovery and FAILOver
|
||
---|---|---|
Recurso
|
NATS
|
Kafka
|
Tempo de Falha
|
Sub-segundo (Reconexão do Cliente mais Rápida)
|
Mais Lento (Depende do Processo de Eleição do Líder)
|
Recuperação sem Interrupções
|
Clientes se reconectam automaticamente sem interrupção
|
Algum tempo de inatividade durante a eleição do líder
|
Risco de Perda de Dados
|
Mínimo com replicação (JetStream)
|
Mínimo se a replicação e ISR estiverem configurados
|
3. Padrões de Mensagem
NATS
O NATS utiliza mensagens baseadas em assunto. Isso permite que serviços e fluxos usem padrões de Pub-Sub, Solicitação-Resposta e Assinante de Fila. Os assuntos no NATS podem ser construídos com hierarquia e curingas. Um único fluxo NATS pode armazenar vários assuntos e os aplicativos do cliente podem usar filtragem no lado do servidor para receber apenas os assuntos de interesse. A conexão no NATS é bidirecional e permite que os clientes publiquem e se inscrevam ao mesmo tempo. O NATS também suporta Filas muito semelhantes ao RabbitMQ.
Kafka
Os Streams no Kafka suportam mensagens de Pub-Sub e baseadas em tópicos. O balanceamento de carga pode ser alcançado por meio de grupos de Consumidores e particionamento dos tópicos.
4. Garantias de Entrega
NATS
O NATS suporta várias garantias de entrega. O NATS sozinho pode suportar uma garantia de entrega no máximo uma vez. Os servidores NATS com JetStream habilitado podem suportar mais dois tipos de garantias. São as garantias “pelo menos uma vez” e “exatamente uma vez”. O NATS pode enviar ‘acks’ para mensagens individuais. Consulte a documentação oficial do NATS para os vários ‘acks’ que ele suporta. Com base no tipo de ‘acks’, o NATS pode reenviar mensagens.
Kafka
O Kafka suporta garantias pelo menos uma vez e exatamente uma vez. A ordenação de mensagens é garantida no nível da Partição. A ordenação global não é possível no Kafka.
5. Retenção e Persistência de Mensagens
NATS
O NATS suporta persistência em memória e baseada em arquivos. Existem várias opções para reproduzir a mensagem. A reprodução de mensagens pode ser por tempo, contagem ou número de sequência.
Kafka
O KAFKA suporta apenas persistência baseada em arquivos. As mensagens podem ser reproduzidas a partir do último, do mais antigo ou de um offset específico. A Compactação de Log é suportada no KAFKA.
6. Idiomas e Plataforma
NATS
Quarenta e oito tipos de clientes conhecidos. Qualquer arquitetura que suporte GOLANG pode suportar servidores NATS.
Kafka
Dezoito tipos de clientes conhecidos. Servidores Kafka podem ser executados em plataformas que suportam JVM.
Casos de Uso
Caso de Uso 1
Requisitos
Temos uma plataforma de dados com um pipeline de streaming. A plataforma usa o motor Apache Flink para streaming em tempo real e o Apache Beam para escrever o pipeline de análise. Abaixo estão os principais requisitos:
- Processamento de mensagens com alto rendimento e baixa latência
- Suporte para checkpoint e tratamento de contra pressão
- Manuseio de mensagens em MB
- Durabilidade e persistência de mensagens
Comparação
Vantagens do Kafkas:
- Alto rendimento
- Retenção de dados com políticas de retenção configuráveis e replicação de dados para tolerância a falhas
- Suporte para pelo menos uma garantia de entrega de mensagem
- Leitura de mensagens a partir de offsets mais antigos/mais recentes/específicos
- ‘Acks’ do lado do servidor para entrega confiável
- Manuseio de grandes fluxos de dados e mensagens de grande tamanho
- Suporte para Tópico de Compactação
Desvantagens do Kafka:
- Alto uso de recursos. Nosso cluster era local e com recursos limitados
- Kafka é apenas quase em tempo real
Vantagens do NATS:
- Alto desempenho com uso mínimo de recursos. O nosso é um cluster local com restrições de recursos
- Suporte para pelo menos uma vez. Estávamos procurando uma garantia de pelo menos uma vez
- Processamento de mensagens com baixa latência
Desvantagens do NATS:
- Sem conectores para Flink/Beam, portanto, a integração era difícil
- Redução de desempenho com o tamanho da mensagem
Decisão Final
Após uma análise cuidadosa, o Kafka foi escolhido. Tivemos que fazer um compromisso entre o uso de recursos e os outros benefícios que o Kafka oferecia, especialmente a boa integração disponível com Apache Beam e Flink. Outra vantagem do Kafka era seu manuseio de grandes tamanhos de mensagem e processamento de mensagens de alto throughput.
Caso de Uso 2
Requisitos
Gerenciar os eventos gerados em um cluster local, Ex: Logs de Auditoria. Os eventos devem ser processados com baixa latência. E suportar a comunicação entre microserviços. Durabilidade e persistência não eram um requisito. O tamanho da mensagem era pequeno. Não havia necessidade de fazer análises sobre os eventos. Estávamos em um ambiente restrito. O uso de recursos e a pegada de memória devem ser mínimos.
Decisão
Por que o NATS foi escolhido:
- Uso eficiente de recursos
- Manuseio de eventos com baixa latência.
- Uma vez que é uma aplicação Go, a pegada de memória é muito baixa
- Capacidade de lidar com tamanhos pequenos de mensagens
- Suporte de Solicitação-Resposta que pode auxiliar na comunicação de Microsserviços
- Quando o JetStream não está configurado, as mensagens não são armazenadas
Por que o Kafka não foi escolhido:
- Por padrão, as mensagens são armazenadas em disco
- O uso de recursos é alto em comparação com o NATS
- Uma vez que necessita do JVM, a pegada de memória é muito alta
Resumo
A escolha entre Kafka e NATS depende dos requisitos específicos em três áreas-chave: Arquitetura e Complexidade, Desempenho e Escalabilidade, e Garantias de Entrega de Mensagens. Kafka é ideal para sistemas que requerem streaming de eventos robusto, armazenamento durável e capacidades avançadas de processamento, mas vem com maior complexidade. Já o NATS é leve, fácil de gerenciar, e se destaca em cenários de baixa latência e alto rendimento com necessidades de mensagens mais simples.
Ao projetar um sistema de mensagens distribuído, avalie cuidadosamente essas áreas para alinhar sua escolha com os objetivos e restrições de sua aplicação. Tanto o Kafka quanto o NATS são ferramentas poderosas, e a escolha certa dependerá do seu caso de uso.
Áreas-chave a serem consideradas antes de escolher entre Kafka e NATS:
- Arquitetura e complexidade
- Alta disponibilidade e desempenho
- Garantias de entrega de mensagens
Kafka é ideal para sistemas distribuídos que requerem streaming de eventos, armazenamento durável e capacidades avançadas de processamento. No entanto, o Kafka vem com alto uso de recursos e uma pegada de memória. E a complexidade de gerenciamento é muito alta em comparação com o NATS.
Por outro lado, o NATS é leve e fácil de gerenciar. O processamento de mensagens de baixa latência é a capacidade de assinatura do NATS.
Em última análise, tanto o Kafka quanto o NATS são ferramentas poderosas para lidar com eventos. A escolha depende de casos de uso específicos.
Source:
https://dzone.com/articles/kafka-vs-nats-message-processing