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(同步副本)的概念。如果領導者失效,則其中一個ISR成為領導者。對於集群元數據管理和領導者選舉,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’以實現可靠交付
  • 處理海量數據流和大型消息大小
  • 支持壓縮主題

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