Queue, Event Bus, Stream: Quale usare?
Il mondo delle Event-Driven Architecture (EDA) è vasto e complesso, e spesso ci si trova a dover scegliere tra diverse soluzioni per incanalare gli eventi all’interno di un sistema nella maniera corretta. Tra le soluzioni più comuni ci sono Queue, Event Bus e Stream, ognuna con i suoi pro e contro.
Queue
Per queue si intende una serie di eventi immagazzinati con metodologia FIFO (First In, First Out), ovvero il primo evento a essere inserito è il primo a essere processato. Questo comporta che i messaggi vengano processati in ordine di arrivo, garantendo che nessun messaggio venga perso. Alla lettura di un messaggio, la coda lo rimuove, garantendo che non venga processato più di una volta tramite un meccanismo denominato acknowledgement.
Una queue viene solitamente usata quando i messaggi inseriti all’interno di essa verranno processati solo ed esclusivamente da un consumer (ossia, il destinatario). In questa circostanza è molto semplice scalare il consumer attivandone più istanze, facendo sì che ognuna di esse processi un messaggio diverso. Questo permette di processare un gran numero di messaggi in parallelo, riducendo i tempi di elaborazione.
Solitamente ad una queue viene associato un layer di persistenza, ovvero la capacità di immagazzinare i messaggi anche in caso di guasto o riavvio del sistema. Questo permette di garantire che nessun messaggio venga perso, anche in caso di problemi.
Si sconsiglia l’utilizzo di una queue quando è necessario che consumer differenti processino lo stesso messaggio, in quanto questo comporterebbe la duplicazione del messaggio e la conseguente elaborazione multipla dello stesso.
Event Bus
Per Event Bus si intende una serie di eventi immagazzinati con metodologia FIFO, esattamente come nel caso di una queue. Alla lettura di un messaggio, però, l’Event Bus non lo rimuove, permettendo a più consumer di processarlo, e solo quando tutti i consumer avranno terminato, il messaggio verrà rimosso.
Un Event Bus viene solitamente usato quando è necessario che più consumer processino lo stesso messaggio, in quanto nasce proprio per questo scopo.
Tipicamente, a differenza di una queue, un Event Bus non garantisce la persistenza dei messaggi. Questo comporta che, in caso di guasto o riavvio del sistema, i messaggi possano essere persi.
Stream
Per stream intendiamo un flusso continuo di eventi, capace di coniugare molti degli aspetti positivi di queue ed event bus. La differenza rispetto alle due soluzioni precedenti è che quando un nuovo consumer si connette a uno stream, esso riceverà tutti i messaggi a partire dall’inizio dello stream, garantendo la replayability, ovvero la capacità di rileggere tutti i messaggi a partire da un certo punto del tempo.
Uno stream è particolarmente utile quando è necessario processare un gran numero di messaggi in parallelo, in quanto permette di scalare facilmente il numero di consumer attivi. Inoltre, la replayability permette di rileggere i messaggi in caso di errore o di necessità di rielaborazione.
Solitamente a uno stream è associata una persistenza dei messaggi, garantendo che nessun messaggio venga perso in caso di guasto o riavvio del sistema, anche se il valore principale di questa soluzione è in realtà la bassa latenza con il quale i messaggi vengono processati.
Conclusione
Come per la maggior parte delle decisioni di architettura, la scelta tra queue, event bus e stream dipende dalle esigenze specifiche del sistema. In generale, si può dire che:
- Una queue è adatta quando i messaggi devono essere processati da un solo consumer e la persistenza è fondamentale.
- Un Event Bus è adatto quando i messaggi devono essere processati da più consumer e la persistenza non è fondamentale.
- Uno stream è adatto quando i messaggi devono essere processati da più consumer e la replayability è fondamentale.
È possibile combinare le tre soluzioni all’interno di un sistema, utilizzando ciascuna di esse per i compiti per cui è più adatta. Ad esempio, spesso si utilizza un Event Bus per canalizzare tutti gli eventi all’interno del sistema, e molteplici queue filtrate per i propri eventi di interesse, che pescano dal bus stesso, e che andranno a servire i vari consumer. Parallelamente, si può utilizzare uno stream per alimentare una porzione che necessiti di real-time data processing, come un sistema di analytics o di monitoraggio.