Kafka与NATS:消息处理的比较

在分布式架构中,系统之间的通信构成了整个基础设施的基础。基础设施的性能、可扩展性和可靠性很大程度上取决于事件/消息/数据的交换和持久化方式。

Kafka 和 NATS 是处理流式数据和消息的两个流行工具。它们具有不同的架构和不同的性能特征。它们适用于特定的使用案例。在本文中,我们将比较 NATS 与 Kafka 的特性,并解释我在工作中处理的使用案例。

1. 架构和复杂性

NATS

NATS 基础设施有两个主要组件:

Core NATS

Core NATS 是基础消息框架。它支持发布-订阅(允许消息广播到多个订阅者)、请求-响应(实现同步通信)和队列组(在组内实现多个订阅者之间的负载均衡)。

它设计用于简单性、低延迟、高性能和可扩展性。在需要低延迟和高吞吐量的场景中表现非常出色。然而,Core NATS 仅提供非保证交付,意味着消息仅传递给活跃的订阅者。如果订阅者离线,数据将会丢失。当速度和规模优先于持久性时,Core NATS 是一个不错的选择。

JetStream

JetStream 为 Core NATS 带来了持久性功能。这有助于提供消息的耐久性和可靠性。它允许消息或事件被持久化(磁盘或内存)并可以重放。持久化的消息可以重放给新的或恢复中的订阅者。使用 JetStream,用户可以获得额外的功能:

  1. 流保留:消息被保留的时间。可以基于大小、时间或消费者限制。
  2. 消费者耐久性:使消费者能够从上次中断的地方恢复。
  3. 消息确认:确保交付的可靠性。

JetStream 为 Core NATS 增加了一层复杂性。然而,这带来了支持保证交付、持久性和重放性用例的重要特性。

Kafka

Kafka 是建立在基于日志的经纪人架构上的分布式消息系统。Kafka中的数据被安排到主题中,并可以有多个分区。消费者连接到这些分区。这种架构允许Kafka对单个主题进行消息消费的并行化。数据按顺序附加到主题/分区。Kafka保证分区内的顺序。在Kafka集群中,可以有许多经纪人,每个经纪人管理一个主题和分区列表。为了实现高可用性和防止数据丢失,Kafka依赖于复制因子,其中分区在多个Kafka经纪人之间复制。正如您所看到的,有多个组件必须管理才能实现高吞吐量、容错性、数据保留和横向扩展性。这增加了Kafka的架构复杂性。

2. 高可用性和性能 

NATS 

集群中的所有节点都以网格形式相互连接,客户端可以连接到任何节点。这种配置避免了单点故障。如果一个节点失败,客户端会自动连接到其他节点,无需任何手动干预。这被称为NATS中的自愈。启用JetStream的节点在所有节点之间分配流。流在网格集群中的JetStream启用节点之间高度管理和负载平衡。 

JetStream还支持在多个集群或节点之间进行数据镜像。在JetStream中,每个流都选出领导者。可以配置每个流的复制。所有这些措施都确保了NATS中的耐用性和可用性。

Kafka

Kafka的高可用性基于复制。每个主题可以有一个或多个分区。每个分区在Kafka Broker之间进行复制。这确保了数据的冗余和可用性。Kafka遵循领导者-跟随者的复制机制。领导者负责读取和写入,而跟随者负责复制数据。

Kafka为每个分区维护了一种称为ISR(同步副本)的机制。如果领导者发生故障,ISRs中的一个将成为领导者。对于集群元数据管理和领导者选举,Kafka依赖于Zookeeper(在较新版本中为KRaft)。

Performance and Scalability
特性
NATS
Kafka
吞吐量
高或低延迟。针对小消息进行了优化
针对高吞吐量和大消息进行了优化
扩展性
支持横向扩展和集群
支持横向扩展和分区
延迟
低于毫秒
毫秒
Recovery and FAILOver
特性
NATS
Kafka
故障转移时间
亚秒级(客户端重新连接更快)
较慢(取决于领导者选举过程)
无缝恢复
客户端自动连接,无中断
部分中断在领导者选举期间
数据丢失风险
通过复制(JetStream)最小
如果配置了复制和ISR,风险最小

3. 消息模式

NATS

NATS使用基于主题的消息传递。这使得服务和流可以使用发布-订阅、请求-响应和队列订阅者模式。NATS中的主题可以构建层次结构和通配符。单个NATS流可以存储多个主题,客户端应用程序可以使用服务器端过滤来仅接收感兴趣的主题。NATS中的连接是双向的,允许客户端同时发布和订阅。NATS还支持类似于RabbitMQ的队列。

Kafka

Kafka中的流支持发布订阅和基于主题的消息传递。通过消费者组和对主题进行分区可以实现负载均衡。

4. 传递保证

NATS

NATS支持各种传递保证。NATS本身可以支持至多一次的传递保证。启用JetStream的NATS服务器可以支持另外两种类型的保证,即“至少一次”和“恰好一次”的保证。NATS可以向单独的消息发送“确认”。请参考NATS官方文档以了解它支持的各种“确认”类型。根据“确认”类型,NATS可以重新传递消息。

Kafka

Kafka支持至少一次和恰好一次的保证。消息排序在分区级别上是有保证的。在Kafka中不可能实现全局排序。

5. 消息保留和持久化

NATS

NATS支持基于内存和文件的持久化。有几种选项可以重放消息。消息的重放可以通过时间、计数或序列号进行。

Kafka

KAFKA仅支持基于文件的持久化。消息可以从最新、最早或特定偏移量进行重放。KAFKA支持日志压缩。

6. 语言和平台

NATS

四十八种已知的客户端类型。任何支持GOLANG的架构都可以支持NATS服务器。

Kafka

十八种已知的客户端类型。Kafka服务器可以在支持JVM的平台上运行。

使用案例

使用案例 1

需求

我们有一个带有流水线的数据平台。该平台使用Apache Flink引擎进行实时流处理,使用Apache Beam编写分析流水线。以下是关键需求:

  1. 高吞吐量和低延迟的消息处理
  2. 支持检查点和背压处理
  3. 处理以MB为单位的消息
  4. 消息的持久性和持久化

比较

Kafka优势s

  • 高吞吐量
  • 具有可配置的保留策略并为容错性复制数据的数据保留
  • 支持至少一种消息传递保证
  • 从最早/最新/特定偏移量读取消息
  • 服务器端的‘acks’以确保可靠传递
  • 处理大规模数据流和大消息大小
  • 支持Compaction主题

Kafka缺点

  • 高资源使用。我们的集群是在本地且资源受限
  • Kafka 仅支持近实时

NATS 的优点:

  • 高性能且资源使用最小。我们的集群是在本地且资源受限
  • 支持至少一次。我们正在寻找至少一次的保证
  • 低延迟消息处理

NATS 的缺点:

  • 没有用于 Flink/Beam 的连接器,因此集成比较困难
  • 随着消息大小的增加性能下降

最终决定

经过仔细分析,选择了 Kafka。我们必须在资源使用和 Kafka 提供的其他好处之间做出权衡,特别是与 Apache Beam 和 Flink 的良好集成。Kafka 的另一个优点是其处理大消息尺寸和高吞吐量消息处理的能力。

用例 2

需求

处理在本地集群中生成的事件,例如:审计日志。事件应以低延迟进行处理,并支持微服务通信。耐久性和持久性不是要求。消息大小很小。无需对事件进行任何分析。我们处于一个受限的环境中。资源使用和内存占用应尽量减少。

决策

选择 NATS 的原因:

  • 高效的资源使用
  • 低延迟事件处理。
  • 由于它是一个 Go 应用程序,内存占用量非常低
  • 能够处理小消息大小
  • 支持请求-回复,有助于微服务通信
  • 当 JetStream 未配置时,消息不会被存储

为什么没有选择 Kafka:

  • 默认情况下,消息会被存储在磁盘上
  • 与 NATS 相比,资源使用率更高
  • 由于需要 JVM,内存占用量非常高

总结

在 Kafka 和 NATS 之间的选择取决于三个关键领域的具体要求:架构与复杂性,性能与可伸缩性,消息传递保证。Kafka 适用于需要强大的事件流处理、持久存储和高级处理能力的系统,但复杂度更高。另一方面,NATS 轻量级,易于管理,在低延迟、高吞吐量场景中表现出色,适用于较简单的消息需求。

在设计分布式消息系统时,仔细评估这些领域,以使您的选择与应用程序的目标和限制相一致。Kafka 和 NATS 都是强大的工具,正确的选择将取决于您的用例。

在选择 Kafka 和 NATS 之间之前需要考虑的关键领域:

  1. 架构与复杂性
  2. 高可用性和性能
  3. 消息传递保证

Kafka 非常适合需要事件流处理、持久存储和先进处理能力的分布式系统。然而,Kafka 的资源使用率高,并且内存占用较大。而且,与 NATS 相比,管理复杂性非常高。

另一方面,NATS 轻量且易于管理。低延迟消息处理是 NATS 的标志性特性。

最终,Kafka 和 NATS 都是强大的事件处理工具。选择取决于具体的使用案例。

Source:
https://dzone.com/articles/kafka-vs-nats-message-processing