Apache Kafka - Tutorial
Apache Kafka è una piattaforma di Event-Streaming Processing, progettata per processare grandi moli di dati in tempo reale, abilitando la creazione di sistemi scalabili, con un elevato throughput e bassa latenza. Da Design prevede anche la persistenza dei dati sul cluster (server princiale e repliche) garantendo un elevata alta-affidabilità.
In questo post andremo a vedere come creare un cluster Kafka per l’ambiente di sviluppo, la creazione dei Topic, la logica delle partizioni e dei gruppi di consumer, ed ovviamente il modello publish-subscribe.
I requisiti per svolgere l’esercitazione sono i seguenti:
- Java 8
- Download dell’ultima versione di Apache Kafka
N.B.: Tutti i comandi sono lanciati su macchina Windows (KAFKA_HOME/bin/windows/), se siete su ambiente Linux usate il path (KAFKA_HOME/bin).
Concetti Fondamentali
Apache Kafka è un sistema distribuito costituto da server (cluster di uno o più server) e client che comunicano tramite il protocollo TCP. Può essere deployato su hardware bare-metal, macchine virtuali e container (on-premise e cloud).
Kafka tra le varie funzionalità, fornisce anche delle API per l’implementazione del modello di Messaggistica Publish-Subscribe:
Questo post si concentra sulle Consumer e Producer API, ed i suoi concetti principali:
- Evento / Record: E’ il messaggio che viene scritto e letto dalle applicazioni. E’ composto da una chiave, un valore ed un timestamp.
- Topic: E’ colui che si occupa di organizzare, archiviare e raggruppare una serie di Eventi / Records.
- Partizione: Le sottosezioni in cui è suddiviso un topic. Utile per la scalabilità delle applicazioni.
- Offset: Identificativo univoco di un Evento / Record all’interno di una Partizione - Topic.
- Producer: Colui che invia i messaggi (Evento / Record)
- Consumer: Colui che riceve i mesaggi (Evento / Record)
Configurazione di un Cluster Kafka
Una volta effettuato il download della release di Kafka, è sufficiente scompattare l’archivio ed eseguire i seguenti comandi:
cd <KAFKA_DIR>
bin/windows/zookeeper-server-start.bat config/zookeeper.properties &
bin/windows/kafka-server-start.bat config/server.properties &
Ora che abbiamo startato il nostro cluster (single-server) Kafka, possiamo creare il nostro primo topic:
bin/windows/kafka-topics.bat --zookeeper localhost --create --topic MIO-TOPIC-UNO --partitions 2 --replication-factor 1
Nel comando mostrato abbiamo specificato:
- MIO-TOPIC-UNO come nome del Topic
- 2 Partizioni
- 1 Fattore di Replica (deve essere minore o uguale al numero dei nodi nel cluster di Kafka; dato che stiamo eseguendo un Cluster single-server è necessario indicare come valore 1 altrimenti riceveremo un errore)
Ora se tutto è andato bene, con il seguente comando dovremmo vedere la lista dei nostri Topic presenti sul Cluster:
bin/windows/kafka-topics.bat --zookeeper localhost --list
Per avere maggiori informazioni sul topic, ad esempio vedere il numero di partizioni, possiamo eseguire:
bin/windows/kafka-topics.bat --zookeeper localhost
--topic MIO-TOPIC-UNO --describe
Publish-Subscribe
Per prima cosa andiamo a creare due Consumer in ascolto sul nostro Topic. Dovremo lanciare il comando su due Terminali differenti:
bin/windows/kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic MIO-TOPIC-UNO
Per pubblicare un messaggio sul Topic, dobbiamo creare il nostro Producer:
bin/windows/kafka-console-producer.bat --broker-list localhost:9092 --topic MIO-TOPIC-UNO
Si aprira un terminale dove potremo inserire un testo e con la pressione del tasto Enter inviare il messaggio.
Il risultato dovrebbe essere come l’immagine sotto:
Ricapitolando, abbiamo creato due Consumer in ascolto sul nostro Topic e un Producer che ha inviato due messaggi, entrambi letti da tutti i Consumer.
Gruppi di Consumer vs Partizioni
Nei paragrafi precedenti abbiamo visto come ogni Consumer riceva qualsiasi messaggio presente su un topic. In uno scenario in cui viene richiesto di scalare l’applicazione che scoda i messaggi, andremo a replicare i Consumer, ma questi ultimi riceverebbero tutti i messaggi (a seconda dell’applicazione questo potrebbe essere un problema di duplicazione delle informazioni/dati).
Ma se volessimo creare uno scenario in cui un insieme di Consumer ricevano solo una volta un certo messaggio, qui abbiamo la necessità di utilizzare i “Gruppi di Consumer”.
Se i Consumer sono parte di un Gruppo, le partizioni del Topic (e quindi anche gli Eventi / Record) saranno distribuite tra i membri del Gruppo.
In particolare:
- I = Numero di Consumatori dello stesso Gruppo
- C = Numero di Partizioni
Avremo i seguenti scenari possibili:
- se I > C ; ogni Consumer avrà assegnata la sua partizione, una volta terminate le partizioni i Consumer rimanenti riesteranno senza partizioni assegnate.
- se I= C ; ogni Consumer avrà una e una sola partizione;
- se I< C ; le partizioni saranno distribuite in maniera uniforme tra i membri del Gruppo.
Su Apache Kafka è anche possibile lavorare sulle logiche di partizionamento dei Record, scrivendo un record su una specifica partizione; in caso questo non venga specificato Apache Kafka procedere con un meccanismo di round-robin.
Publish-Subscribe con Gruppi di Consumer (Parte 1)
Procediamo nella creazione di due Consumer in ascolto sul nostro Topic, avendo lo stesso gruppo di consumer. Dovremo lanciare il comando su due Terminali differenti:
bin/windows/kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic MIO-TOPIC-UNO --group GRUPPO-CONSUMER-UNO
Come già visto, per pubblicare un messaggio sul Topic dobbiamo creare il nostro Producer:
bin/windows/kafka-console-producer.bat --broker-list localhost:9092 --topic MIO-TOPIC-UNO
Il risultato dovrebbe essere come l’immagine sotto:
Abbiamo visto come creando un Gruppo di Consumer questi ricevano solamente una volta il messaggio inviato dal Producer; e non come nell’esercizio “Publish-Subscribe” dove i Consumer ricevevano tutti i messaggi.
Publish-Subscribe con Gruppi di Consumer (Parte 2)
A differenza dell’esercizio sopra, andiamo a creare tre Consumer (uno in più del numero di partizioni presenti sul Topic).
bin/windows/kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic MIO-TOPIC-UNO --group GRUPPO-CONSUMER-UNO
Pubblicare un messaggio sul Topic creando il nostro Producer:
bin/windows/kafka-console-producer.bat --broker-list localhost:9092 --topic MIO-TOPIC-UNO
Il risultato dovrebbe essere come l’immagine sotto:
Come vediamo solamente due Consumer stanno scodando i messaggi, in quanto i primi due Consumer ha preso le due partizioni disponibili ed il terzo Consumer non è agganciato a nessuna partizione e quindi non riceve i messaggi.
Se volete, potete aumentare il numero delle partizioni sul Topic e provare ad eseguire nuovamente lo scenario. Vedrete poi che tutti e tre scoderanno i messaggi. Per incrementare il numero di partizioni sul Topic possiamo eseguire il seguente comando:
bin/windows/kafka-topics.bat --zookeeper localhost --alter --topic MIO-TOPIC-UNO --partitions 3
Considerazioni Finali
Andando a mettere insieme le nozioni viste nel post, andiamo a creare:
- 2 Consumer nel Gruppo “GRUPPO-CONSUMER-UNO”
- 1 Consumer non associato a nessun Gruppo
e vedremo il seguente comportamento:
Dove i messaggi inviati dal Producer, sono suddivisi tra i due gruppi di Consumer (GRUPPO-CONSUMER-UNO e quello blank).
Conclusioni
In questo post abbiamo esposto i principali concetti riguardanti il funzionamento di Apache Kafka, concentrandoci in particolare sull’utilizzo delle Consumer e Producer API e delle sue potenzialità in termini di scalabilità.
Alcuni link utili per l’approfondimento: