Introduzione ad Apache Kafka

Una rapida introduzione su Apache Kafka: vantaggi e svantaggi ed alcuni casi d’uso dove Kafka eccelle.

Un po di background.

Per decenni, le applicazioni sono state sviluppate usando una architettura monolitica: l’intero sistema si basava su una singola applicazione (con, generalmente, un singolo codice sorgente). In una applicazione monolitica tradizionale, tutte le funzioni sono gestite e servite da un sistema centralizzato e le sue componenti interne non richiedono API per comunicare tra di loro. Inoltre, i dati vengono persistiti in un database relazionale: ogni tabella rappresenta una entità con uno specifico stato; ad esempio, una tipica applicazione e-commerce userebbe tabell come utente, articolo, ordine, fattura…

monolithic

Un trend recente nell’architettura del Software è quello di dividere l’applicazione in  molti componenti (microservices), abbastanza piccoli da essere sviluppati, rilasciati, scalati ed evolvere indipendentemente l’uno dall’altro. In una tipica architettura event-driven, i microservizi parlano tra di loro tramite eventi: un servizio produce eventi mentre altri reagiscono a questi eventi invece di essere chiamati direttamente.

Il risultato è un’architettura con servizi che sono scalabili e indipendenti uno dall’altro. Usare Kafka per una comunicazione asincrona tra microservizi può aiutare a evitare colli di bottiglia tipici delle architetture monolitiche. Dato che Kafka è altamente disponibile, interruzioni temporanee di un servizio sono risolte localmente senza ripercussioni principali sugli altri sistemi.

log

L’architettura di Apache Kafka

Apache Kafka è una piattaforma di streaming distribuita, originariamente sviluppata da Linkedin e in seguito resa open source nel 2011. E’ in grado di gestire logs chiamati topics. Un topic è una collezione ordinata, append-only, di eventi (records) persistiti in modo durevole e fault-tolerant: i record sono scritti sul disco e replicati (1). I record vengono aggiunti alla fine del log e le letture procedono da sinistra verso destra; ad ogni elemento è assegnato un indice progressivo.

Gli eventi vengono scritti dai producers. Queste entità serializzano e pubblicano messaggi su uno o più topic in Kafka. Inoltre comprimono e ripartiscono il carico degli eventi tra i brokers attraverso il partizionamento. Ci sono molti tipi di producers: componenti di un’applicazione, dispositivi IoT, agenti di monitoring.

Gli eventi vengono letti dai consumers. Questi leggono i messaggi dai topic ai quali sono registrati. Spesso, i consumers appartengono ad un consumer group: ogni consumer in un dato consumer group sarà responsabile di leggere un sottoinsieme di partizioni di ogni topic a cui è sottoscritto. Molto spesso, le stesse entità possono agire sia da consumers che da producers.

Kafka si comporta, in un certo senso, da intermediario tra applicazioni che generano eventi e applicazioni che li consumano.

producer consumer

Kafka è disegnato per gestire applicazioni pesanti ed accodare grandi quantità di messaggi in un topic. Per garantire la scalabilità, ogni topic è diviso in molteplici partizioni e ogni partizione è gestita su un broker diverso. Per garantire la tolleranza ai guasti e un’elevata disponibilità. ogni topic può essere replicato così da avere molteplici broker con una copia dei dati nel caso in cui il broker fallisce.

partition

Pro e contro di Apache Kafka.

Siccome è importante conoscere i limiti di ogni tecnologia, ecco una lista di pro e contro di Kafka.

Pro:

  • High-throughput e scalabilità: Kafka può processare milioni di messaggi per secondo ed è in grado di frammentare i topics in partizioni al fine di garantire scalabilità ed elevato throughput su letture/scritture sequenziali. Nel caso di più producers che scrivono sullo stesso topic attraverso partizioni separate e replicate, e più consumer da molteplici consumer groups che leggono da differenti partizioni, è possibile raggiungere qualunque livello di scalabilità e performance;
  • Bassa latenza: nel range di millisecondi. Questa caratteristica permette di gestire eventi in tempo reale;
  • Tolleranza ai guasti: grazie alla replica dei topic (molteplici copie dei dati), un cluster Kafka è in grado di risolvere automaticamente il fallimento di un broker.
  • Persistenza dei dati  a lungo termine: Kafka è diverso dai tradizionali sistemi di coda di messaggi (come RabbitMQ). Kafka conserva i messaggi anche dopo essere stati consumati per un dato periodo di tempo (di default 7 giorni), mentre RabbitMQ rimuove i messaggi subito dopo che la conferma di un consumer è stata ricevuta. Inoltre non è inusuale avere topic con terabytes di dati.
  • Sicurezza: Kafka fornisce un gran numero di caratteristiche di sicurezza enterprise-grade sia per l’autenticazione che per l’autorizzazione (Kerberos, TLS, Access Control Lists).
  • Kafka clients: Kafka è scritto in Java e Scala, ma la lista di linguaggi di programmazione che fornisce le librerie client per Kafka è lunga (es: Clojure, C#, Go, Groovy, Kotlin, Node.js, Python, Ruby). Ci sono inoltre componenti aggiuntivi della piattaforma Kafka che aiutano l’interoperabilità: REST Proxy, Kafka Connect.

Contro:

  • Complessità operazionale incrementata;
  • Set incompleto di strumenti di monitoraggio.

Casi di uso.

Diamo un’occhiata ai più comuni casi d’uso di Apache Kafka.

  • Tracking dell’attività web: è possibile tracciare l’attività di tutti gli utenti di un sito web  (pagine visitate, prodotti aggiunti a un carrello senza essere acquistati, tempo speso per leggere una pagina, annunci pubblicitari mostrati all’utente). Tutte queste informazioni possono essere pubblicate su un topic dedicato e successivamente processate per monitoraggio, analisi, reportistica o per modificare in tempo reale gli annunci in base alle performance;
  • Comunicazione tra servizi: Kafka è un’eccellente soluzione in un’architettura di microservizi, migliorando l’efficienza e la performance dell’intero sistema. I microservizi usano il meccanismo publish/subscribe per interagire tra di loro; producers e consumers sono pienamente scollegati e agnostici gli uni degli altri, che è un elemento chiave di design per raggiungere l’alta scalabilità;
  • Trattamento dei dati in tempo reale: uno scenario comune è la rilevazione di frodi tramite carte di credito, attraverso il monitoraggio di parametri come la localizzazione e la frequenza delle transazioni;
  • Analisi dei dati IoT: le metriche inviate dai dispositivi IoT sono processati in tempo reale e su scala. Esempi: posizioni gps di macchine per fornire consigli sul traffico in tempo reale; localizzazione su applicazioni mobile per fornire consigli per gli acquisti; sensori installati su motori e freni di treni per individuare anomalie.