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 lidar com streaming e mensageria. Elas têm arquiteturas diferentes e características de desempenho distintas. Elas são adequadas para casos de uso específicos. Neste artigo, vamos comparar os recursos do NATS com o Kafka e explicar os casos de uso que abordei no trabalho.
1. Arquitetura e Complexidade
NATS
A infraestrutura do NATS tem dois componentes principais:
Core NATS
O Core NATS é a base da estrutura de mensageria. Isso suporta Publish-Subscribe (permite que as mensagens sejam transmitidas para múltiplos assinantes), Request-Reply (possibilita a comunicação síncrona) e Queue Groups (facilita o balanceamento de carga entre múltiplos assinantes dentro de um grupo).
Isso é projetado para simplicidade, baixa latência, alto desempenho e escalabilidade. Ele desempenha muito bem em cenários que requerem baixa latência e alta capacidade de processamento. No entanto, o Core NATS sozinho fornece 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 Core NATS é uma boa opção quando velocidade e escala têm prioridade sobre durabilidade.
JetStream
JetStream traz capacidades de persistência para o topo do Core NATS. Isso ajudou a fornecer durabilidade e confiabilidade de mensagens. Permite que mensagens ou eventos sejam persistidos (disco ou memória) e retransmitidos. Mensagens persistidas podem ser retransmitidas para assinantes novos ou em recuperação. Com o 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 de consumidor.
- Durabilidade do consumidor: Permitindo que os consumidores retomem de onde pararam.
- Reconhecimento de mensagem: Isso garante a confiabilidade da entrega.
O JetStream adiciona uma camada de complexidade ao Core NATS. No entanto, isso traz o recurso importante de suportar os casos de uso de entrega garantida, persistência e capacidade de retransmissão.
Kafka
O Kafka é um sistema de mensagens distribuído construído com uma arquitetura de broker 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 ao Kafka paralelizar 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 brokers, cada um gerenciando uma lista de tópicos e partições. Para alcançar alta disponibilidade e evitar perda de dados, o Kafka depende de um fator de replicação, onde as partições são replicadas em vários brokers 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 arquitetônica 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 streams entre todos os nós. Os streams são altamente gerenciados e balanceados entre os nós habilitados para JetStream dentro de um cluster em malha.
O JetStream também suporta a replicação de dados em vários clusters ou nós. No JetStream, líderes são eleitos por stream. A replicação de cada stream 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 disponibilidade dos dados. O Kafka segue um mecanismo de replicação Líder-Seguidor. Um líder cuida da leitura e escrita. E o seguidor trabalha na replicação dos dados.
O Kafka mantém algo chamado ISR (Réplicas em Sincronia) para cada partição. Se o líder falhar, uma das ISRs se torna o líder. Para o gerenciamento de metadados do cluster e eleição de líder, o Kafka depende do Zookeeper (KRaft nas versões mais recentes).
Performance and Scalability
|
||
---|---|---|
Recurso
|
NATS
|
Kafka
|
Rendimento
|
Alta ou baixa latência. Otimizado para mensagens pequenas
|
Otimizado para alto rendimento e mensagens grandes
|
Escala
|
Escalável horizontalmente com clustering
|
Escalável horizontalmente com particionamento
|
Latência
|
Submilissegundos
|
Milissegundos
|
Recovery and FAILOver
|
||
---|---|---|
Recurso
|
NATS
|
Kafka
|
Tempo de Failover
|
Sub-segundo (Cliente reconecta mais rapidamente)
|
Mais lento (Depende do processo de eleição do líder)
|
Recuperação Contínua
|
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, Request-Reply e Queue Subscriber. Assuntos no NATS podem ser construídos com hierarquia e curingas. Um único fluxo NATS pode armazenar vários assuntos e aplicativos clientes 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 oferece suporte a Filas muito semelhante 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 oferecer uma garantia de entrega no máximo uma vez. Servidores NATS com JetStream habilitado podem oferecer suporte a dois tipos adicionais de garantias. São elas 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 oferece suporte a 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 oferece suporte a 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. 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 conhecidos de clientes. Todas as arquiteturas que suportam GOLANG podem suportar servidores NATS.
Kafka
Dezoito tipos conhecidos de clientes. Os 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 utiliza 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 de alto rendimento e baixa latência
- Suporte para checkpoint e gerenciamento 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 fluxos de dados massivos e mensagens de grande tamanho
- Suporte para Tópico de Compactação
Desvantagens do Kafka:
- Alto uso de recursos. Nosso cluster estava localizado no local e com restrições de recursos
- O Kafka é apenas em tempo quase real
Vantagens do NATS:
- Alto desempenho com uso mínimo de recursos. O nosso é um cluster no local com restrições de recursos
- Suporte para pelo menos uma vez. Estávamos buscando uma garantia de pelo menos uma vez
- Processamento de mensagens de baixa latência
Desvantagens do NATS:
- Sem conectores para Flink/Beam, portanto, a integração foi 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 equilíbrio entre o uso de recursos e os outros benefícios que o Kafka estava oferecendo, especialmente a boa integração disponível com o Apache Beam e Flink. Outra vantagem do Kafka foi o seu tratamento de tamanhos de mensagem grandes e o processamento de mensagens com alto rendimento
Caso de Uso 2
Requisitos
Manipular os eventos gerados em um cluster no local, Ex: Logs de Auditoria. Os eventos devem ser processados com baixa latência. E suportar a comunicação entre microsserviços. Durabilidade e persistência não eram requisitos. O tamanho da mensagem era pequeno. Não era necessário fazer análises nos 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 de baixa latência.
- Como se trata de 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 ajudar na comunicação entre 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
- Como precisa do JVM, a pegada de memória é muito alta
Resumo
A escolha entre Kafka e NATS depende de requisitos específicos em três áreas-chave: Arquitetura e Complexidade, Desempenho e Escalabilidade, e Garantias de Entrega de Mensagens. O Kafka é ideal para sistemas que necessitam de transmissão de eventos robusta, armazenamento durável e capacidades avançadas de processamento, mas vem com maior complexidade. O NATS, por outro lado, é 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 limitaçõ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 exigem 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 distintiva 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