在分散式架構中,系統之間的通信形成整個基礎設施的基礎。基礎設施的性能、可擴展性和可靠性很大程度上取決於事件/消息/數據的交換和持久化方式。
Kafka 和 NATS 是兩個處理流數據和消息的熱門工具。它們具有不同的架構和不同的性能特徵。它們適用於特定的用例。在本文中,我們將比較 NATS 與 Kafka 的特點,並解釋我在工作中處理的用例。
1. 架構和複雜性
NATS
NATS 基礎設施有兩個主要組件:
Core NATS
Core NATS 是基礎消息框架。它支持發佈-訂閱(允許將消息廣播給多個訂閱者)、請求-回覆(實現同步通信)和隊列組(在組內實現多個訂閱者之間的負載平衡)。
它被設計為簡單、低延遲、高性能和可擴展性。在需要低延遲和高吞吐量的情況下表現非常好。然而,單獨的 Core NATS 只提供非保證交付,這意味著消息僅傳遞給活躍的訂閱者。如果訂閱者離線,數據將丟失。當速度和規模優先於持久性時,Core NATS 是一個不錯的選擇。
JetStream
JetStream 將持久性功能帶到 Core NATS 的頂部。這有助於提供消息的持久性和可靠性。它允許消息或事件被持久化(磁盤或內存)並重放。持久化的消息可以重放給新的或正在恢復的訂閱者。有了 JetStream,用戶可以獲得額外功能:
- 流保留:消息保留時間長短。可以基於大小、時間或消費者限制。
- 消費者持久性:使消費者可以從上次離開的位置繼續。
- 消息確認:這確保了交付的可靠性。
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編寫分析管道。以下是主要需求:
- 高吞吐量和低延遲消息處理
- 支持檢查點和背壓處理
- 處理MB級別的消息
- 消息的持久性和持久化
比較
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之間之前應考慮的關鍵領域:
- 架構和複雜性
- 高可用性和性能
- 消息交付保證
Kafka 非常適合需要事件串流、持久儲存和高級處理能力的分散系統。然而,Kafka 的資源使用和記憶體佔用都相當高。而管理複雜度也遠遠高於 NATS。
另一方面,NATS 輕巧且易於管理。低延遲訊息處理是 NATS 的標誌性能力。
最終,Kafka 和 NATS 都是強大的事件處理工具。選擇取決於具體的使用案例。
Source:
https://dzone.com/articles/kafka-vs-nats-message-processing