In un’architettura distribuita, le comunicazioni tra i sistemi formano le fondamenta dell’intera infrastruttura. Le prestazioni, la scalabilità e l’affidabilità dell’infrastruttura dipendono molto da come eventi/messaggi/dati vengono scambiati e persistiti.
Kafka e NATS sono due strumenti popolari per gestire lo streaming e la messaggistica. Hanno architetture diverse e caratteristiche di prestazione differenti. Sono adatti a casi d’uso specifici. In questo articolo, confronteremo le caratteristiche di NATS con Kafka e spiegheremo i casi d’uso di cui ho trattato al lavoro.
1. Architettura e Complessità
NATS
Infrastruttura NATS ha due componenti principali:
Core NATS
Core NATS è il framework di messaggistica di base. Questo supporta Publish-Subscribe (consente di trasmettere messaggi a più sottoscrittori), Request-Reply (abilita la comunicazione sincrona) e Queue Groups (facilita il bilanciamento del carico tra più sottoscrittori all’interno di un gruppo).
È progettato per la semplicità, la bassa latenza, le alte prestazioni e la scalabilità. Funziona molto bene in scenari che richiedono bassa latenza e alta capacità di elaborazione. Tuttavia, Core NATS da solo fornisce solo consegna non garantita, il che significa che i messaggi vengono consegnati solo ai sottoscrittori attivi. I dati andranno persi se i sottoscrittori sono offline. Core NATS è una buona opzione quando la velocità e la scalabilità hanno la priorità sulla durabilità.
JetStream
JetStream porta capacità di persistenza al top di Core NATS. Questo ha aiutato a fornire durabilità e affidabilità dei messaggi. Consente di persistere messaggi o eventi (su disco o in memoria) e di riprodurli. I messaggi persistenti possono essere riprodotti a nuovi abbonati o a quelli in fase di recupero. Con JetStream, gli utenti ottengono funzionalità aggiuntive:
- Retenzione dello stream: Per quanto tempo i messaggi vengono mantenuti. Può essere basato su dimensione, tempo o limiti del consumatore.
- Durabilità del consumatore: Consente ai consumatori di riprendere da dove si erano interrotti.
- Accettazione del messaggio: Questo assicura l’affidabilità della consegna.
JetStream aggiunge uno strato di complessità a Core NATS. Tuttavia, questo introduce la caratteristica importante di supportare i casi d’uso di consegna garantita, persistenza e riproducibilità.
Kafka
Kafka è un sistema di messaggistica distribuito costruito su un’architettura di broker basata su log. I dati in Kafka sono organizzati in Topic e possono avere più partizioni. I consumatori sono collegati a queste partizioni. Questa architettura consente a Kafka di parallelizzare il consumo di messaggi per un singolo topic. I dati vengono aggiunti a un topic/partizioni in modo sequenziale. Kafka garantisce l’ordinamento in una partizione. In un cluster Kafka, possono esserci molti broker, ciascuno dei quali gestisce un elenco di topic e partizioni. Per raggiungere un’alta disponibilità e prevenire la perdita di dati, Kafka si basa su un fattore di replica, dove le partizioni sono replicate su più broker Kafka. Come puoi vedere, ci sono molteplici componenti che devono essere gestiti per raggiungere un’elevata capacità, tolleranza ai guasti, retention dei dati e scalabilità orizzontale. Questo aumenta la complessità architetturale di Kafka.
2. Alta Disponibilità e Prestazioni
NATS
Tutti i nodi in un cluster sono interconnessi in una rete a maglie, e il client può connettersi a qualsiasi nodo. Questa configurazione evita un punto unico di guasto. Se un nodo fallisce, il client si collega automaticamente agli altri nodi senza alcun intervento manuale. Questo è chiamato auto-guarigione in NATS. Un nodo abilitato JetStream distribuisce i flussi tra tutti i nodi. I flussi sono altamente gestiti e bilanciati nel carico tra i nodi abilitati JetStream all’interno di un cluster a maglie.
JetStream supporta anche il mirroring dei dati tra più cluster o nodi. In JetStream, i leader vengono eletti per ogni flusso. La replica di ciascun flusso può essere configurata. Tutte queste cose garantiscono durabilità e disponibilità in NATS.
Kafka
L’alta disponibilità di Kafka si basa sulla replica. Ogni argomento può avere una o più partizioni. Ogni partizione è replicata attraverso i Broker Kafka. Questo garantisce la ridondanza dei dati e la disponibilità. Kafka segue un meccanismo di replica Leader-Follower. Un leader si occupa di leggere e scrivere. E il follower si occupa di replicare i dati.
Kafka mantiene qualcosa chiamato ISR (In Sync Replicas) per ogni partizione. Se il leader fallisce, uno degli ISR diventa il leader. Per la gestione dei metadati del cluster e l’elezione del leader, Kafka si affida a Zookeeper (KRaft nelle versioni più recenti).
Performance and Scalability
|
||
---|---|---|
Caratteristica
|
NATS
|
Kafka
|
Throughput
|
Alta o bassa latenza. Ottimizzato per messaggi piccoli
|
Ottimizzato per alta capacità e messaggi grandi
|
Scalabilità
|
Scalabile orizzontalmente con clustering
|
Scalabile orizzontalmente con partizionamento
|
Latente
|
Sotto i millisecondi
|
Millisecondi
|
Recovery and FAILOver
|
||
---|---|---|
Caratteristica
|
NATS
|
Kafka
|
Tempo di Failover
|
Sotto il secondo (i Client si riconnettono più velocemente)
|
Più lento (dipende dal processo di elezione del leader)
|
Ripristino senza interruzioni
|
I client si riconnettono automaticamente senza interruzioni
|
Alcun downtime durante l’elezione del leader
|
Rischio di perdita di dati
|
Minimo con replicazione (JetStream)
|
Minimo se la replicazione e l’ISR sono configurati
|
3. Modelli di Messaggio
NATS
NATS utilizza la messaggistica basata su soggetti. Questo consente ai servizi e ai flussi di utilizzare i modelli Pub-Sub, Richiesta-Risposta e Sottoscrittore di Coda. I soggetti in NATS possono essere costruiti con gerarchia e caratteri jolly. Un singolo flusso NATS può memorizzare più soggetti e le applicazioni client possono utilizzare il filtraggio lato server per ricevere solo i soggetti di interesse. La connessione in NATS è bidirezionale e consente ai client di pubblicare e sottoscrivere contemporaneamente. NATS supporta anche la gestione delle code in modo molto simile a RabbitMQ.
Kafka
I flussi in Kafka supportano la messaggistica Pub-sub e basata su argomenti. Il bilanciamento del carico può essere raggiunto tramite gruppi di consumatori e partizionamento degli argomenti.
4. Garanzie di Consegna
NATS
NATS supporta varie garanzie di consegna. NATS da solo può supportare una garanzia di consegna al massimo una volta. I server NATS con JetStream abilitato possono supportare altri due tipi di garanzie. Esse sono le garanzie “almeno una volta” e “esattamente una volta”. NATS può inviare ‘ack’ ai singoli messaggi. Si prega di fare riferimento alla documentazione ufficiale di NATS per i vari ‘ack’ che supporta. In base al tipo di ‘ack’, NATS può riconsegnare i messaggi.
Kafka
Kafka supporta garanzie almeno una volta e esattamente una volta. L’ordinamento dei messaggi è garantito a livello di partizione. L’ordinamento globale non è possibile in Kafka.
5. Conservazione e Persistenza dei Messaggi
NATS
NATS supporta la persistenza in memoria e basata su file. Ci sono diverse opzioni per riprodurre il messaggio. La riproduzione dei messaggi può avvenire per tempo, conteggio o numero di sequenza.
Kafka
KAFKA supporta solo la persistenza basata su file. I messaggi possono essere riprodotti dall’offset più recente, più vecchio o specifico. La Compattazione dei Log è supportata in KAFKA.
6. Linguaggi e Piattaforma
NATS
Quarantotto tipi di client noti. Qualsiasi architettura che supporta GOLANG può supportare i server NATS.
Kafka
Diciotto tipi di client noti. I server Kafka possono funzionare su piattaforme che supportano JVM.
Casi d’uso
Caso d’uso 1
Requisiti
Abbiamo una piattaforma dati con una pipeline di streaming. La piattaforma utilizza il motore Apache Flink per lo streaming in tempo reale e Apache Beam per scrivere la pipeline di analisi. Di seguito sono riportati i requisiti chiave:
- Elaborazione dei messaggi ad alta capacità e bassa latenza
- Supporto per checkpoint e gestione della pressione inversa
- Gestire messaggi in MB
- Durabilità e persistenza dei messaggi
Confronto
Vantaggi di Kafkas:
- Alta capacità
- Conservazione dei dati con politiche di ritenzione configurabili e replica dei dati per tolleranza ai guasti
- Supporto per almeno una garanzia di consegna dei messaggi
- Lettura dei messaggi dagli offset più vecchi/più recenti/specifici
- ‘acks’ lato server per una consegna affidabile
- Gestire enormi flussi di dati e grandi dimensioni dei messaggi
- Supporto per il Topic di Compattazione
Svantaggi di Kafka:
- Alto utilizzo delle risorse. Il nostro cluster era on-premises e vincolato dalle risorse
- Kafka è solo quasi in tempo reale
Vantaggi di NATS:
- Alta prestazione con un utilizzo minimo delle risorse. Il nostro è un cluster on-premises con vincoli di risorse
- Supporto per almeno una volta. Cercavamo una garanzia di almeno una volta
- Elaborazione dei messaggi a bassa latenza
Svantaggi di NATS:
- Nessun connettore per Flink/Beam quindi, l’integrazione era difficile
- Riduzione delle prestazioni con la dimensione del messaggio
Decisione finale
Dopo attenta analisi, è stato scelto Kafka. Abbiamo dovuto fare un compromesso tra l’uso delle risorse e gli altri vantaggi che Kafka offriva, in particolare la buona integrazione disponibile con Apache Beam e Flink. Un altro vantaggio di Kafka era la sua gestione delle grandi dimensioni dei messaggi e l’elaborazione dei messaggi ad alta capacità.
Caso d’uso 2
Requisiti
Gestire gli eventi generati in un cluster on-premises, Es: Log di Audit. Gli eventi devono essere elaborati con bassa latenza. E supportare la comunicazione tra microservizi. La durabilità e la persistenza non erano un requisito. La dimensione del messaggio era ridotta. Nessun bisogno di fare analisi sugli eventi. Eravamo in un ambiente vincolato. L’uso delle risorse e l’impronta di memoria dovevano essere minimi.
Decisione
Perché è stato scelto NATS:
- Uso efficiente delle risorse
- Gestione degli eventi a bassa latenza.
- Poiché è un’applicazione Go, l’impronta di memoria è molto bassa
- Capacità di gestire piccole dimensioni dei messaggi
- Supporto per la richiesta-risposta che può aiutare la comunicazione tra Microservizi
- Quando JetStream non è configurato, i messaggi non vengono memorizzati
Perché Kafka non è stato scelto:
- Per impostazione predefinita, i messaggi vengono memorizzati su disco
- Il consumo di risorse è elevato rispetto a NATS
- Poiché necessita della JVM, l’impronta di memoria è molto alta
Riepilogo
La scelta tra Kafka e NATS dipende dai requisiti specifici in tre aree chiave: Architettura e Complessità, Prestazioni e Scalabilità, e Garanzie di Consegna dei Messaggi. Kafka è ideale per sistemi che richiedono streaming di eventi robusto, archiviazione durevole e capacità di elaborazione avanzate, ma comporta una maggiore complessità. NATS, d’altra parte, è leggero, facile da gestire e si distingue in scenari a bassa latenza e alta capacità con esigenze di messaggistica più semplici.
Quando si progetta un sistema di messaggistica distribuito, valuta attentamente queste aree per allineare la tua scelta agli obiettivi e vincoli della tua applicazione. Sia Kafka che NATS sono strumenti potenti e la scelta giusta dipenderà dal tuo caso d’uso.
Aree chiave da considerare prima di scegliere tra Kafka e NATS:
- Architettura e complessità
- Alta disponibilità e prestazioni
- Garanzie di consegna dei messaggi
Kafka è ideale per sistemi distribuiti che richiedono streaming di eventi, archiviazione durevole e capacità di elaborazione avanzate. Tuttavia, Kafka presenta un alto utilizzo delle risorse e un’impronta di memoria elevata. Inoltre, la complessità di gestione è molto alta rispetto a NATS.
D’altra parte, NATS è leggero e facile da gestire. L’elaborazione di messaggi a bassa latenza è la capacità distintiva di NATS.
In definitiva, sia Kafka che NATS sono potenti strumenti per la gestione degli eventi. La scelta dipende da casi d’uso specifici.
Source:
https://dzone.com/articles/kafka-vs-nats-message-processing