Redis è un noto database NoSQL open source residente in memoria volatile e con persistenza facoltativa. La possibilità di non dovere necessariamente appoggiarsi su dischi di memoria ne ha fin da subito fatto prediligere l'uso, visti i brevissimi tempi di accesso ai dati che lo hanno contraddistinto dai suoi competitor più famosi, quali Cassandra, PostgreSQL, MongoDB e molti altri.
Redis si è inoltre differenziato sin da subito grazie alla sua quantità di strutture dati a disposizione, che ne hanno facilitato la diffusione e l'uso per diverse tipologie di applicazioni.
Con il rilascio dell'ultima versione, Redis 5, è stato compiuto un ulteriore passo avanti e sono stati introdotti gli Stream, che racchiudono un paradigma di comunicazione del tutto nuovo e soprattutto innovativo. In questo approfondimento ci focalizzeremo proprio su di essi.
Cosa sono i Redis Stream
Per certi aspetti, possiamo pensare agli stream di Redis come a dei message queue, ovvero a liste (o, più precisamente, code) in cui è possibile inserire dei messaggi. Ognuno di questi messaggi viene ovviamente contraddistinto da un identificativo, che viene creato di default e che include il timestamp della sua generazione. Queste informazioni vengono memorizzate in una struttura dati di tipo hash.
Il paradigma implementato negli stream è quello del publisher-subscriber, che benchè sia già stato introdotto in Redis 2 con le PUB/SUB
e BLOCKED
list, differisce per alcune interessanti novità.
Gli stream di Redis sono infatti più completi, e forniscono funzioni sia per la persistenza dei messaggi che per la duplicazione degli stessi secondo un'architettura di tipo Master/Slave. Dispongono, inoltre, di una nuova struttura dati, chiamata RadixTree, capace di gestire efficacemente la memoria e la lettura dei vari messaggi.
Le classiche operazioni di PUB/SUB
si occupavano in passato di effettuare delle operazioni bloccanti sul canale di comunicazione, in modo da permettere ai consumatori di poter processare in modo uniforme i messaggi che i produttori avrebbero inserito. Questo meccanismo faceva sì che il messaggio, una volta letto, sarebbe stato consumato per sempre e che, in situazioni di errore o blocco da parte del consumatore, non si sarebbe potuto capire se il messaggio fosse stato effettivamente processato o meno. In aggiunta, solo un consumatore può leggere un determinato messaggio, permettendone così il processamento a uno e uno soltanto.
Si capisce subito che secondo questi meccanismi non è possibile né mantenere una sorta di archivio capace di memorizzare la storia dei messaggi scambiati, né una gestione condivisa degli stessi tra i vari consumatori.
Gli stream di Redis, invece, permettono non solo di mantenere uno storico di ciò che è avvenuto all’interno della rete (dei messaggi scambiati), ma di renderla anche disponibile e visibile a tutti.
Un riepilogo delle migliorie appena annunciate può essere quindi così riassunto:
- I messaggi sono visibili a tutti i consumatori
- Lo storico dei messaggi è archiviato e visibile a tutti
- I consumatori si possono organizzare in gruppi e mandare degli acknowledgement per segnalare il loro stato di buono o cattivo funzionamento
Redis Stream e IRC
Tutte le novità viste finora erano da tempo e in parte già presenti sul noto protocollo di messaggistica istantanea Internet Relay Chat (IRC), da cui Redis ha tratto spunto.
Su IRC, un utente può mandare e ricevere messaggi con tutti gli altri utenti di un canale, senza restrizioni di alcun tipo, com'è facilmente intuibile dalla figura sopra riportata.
Possiamo vedere che gli utenti sono in grado di scambiarsi messaggi se si sono iscritti allo stesso channel IRC (chiamato Topic nella figura). Quando un utente vuole mandare un messaggio su un Topic, quello che deve fare è invocare il comando publish in modo da inserirlo nella queue. Chi sarà registrato su quel channel sarà successivamente in grado di visualizzare il messaggio (tutti i client registrati in esso). Gli stream di Redis si basano esattamente sullo stesso paradigma, e funzionano allo stesso modo fatta eccezione, però, per quanto detto prima sull'archiviazione dei messaggi e su possibili errori sollevati dei consumatori.
Infatti, se un utente IRC dovesse disconnettersi e riconnettersi in un secondo momento (o collegarsi ex-novo), non avrebbe modo di poter recuperare i messaggi scambiati sul channel durante la sua assenza. Con gli stream di Redis questo è possibile.
Usare gli stream di Redis
All&'inizio di questo articolo, abbiamo detto che i messaggi negli stream di Redis possiedono un identificativo associato a un timestamp. Gli stream permettono letteralmente di "appendere" i messaggi a una sua particolare struttura dati, per poterli successivamente far leggere ai vari consumatori.
Le operazioni per permettere tutto ciò sono le seguenti:
Comando | Descrizione |
---|---|
XADD |
Permette di aggiungere un nuovo messaggio |
XRANGE |
Permette di leggere un range di messaggi |
XREAD |
Permette di leggere un nuovo messaggio |
XDEL |
Permette di cancellare uno o più messaggi |
XLEN |
Permette di ottenere la lunghezza di un messaggio |
XTRIM |
Permette di troncare la lunghezza di un messaggio a una dimensione prefissata |
XSETID |
Permette di impostare il numero massimo di identificativo per i messaggi |
Qualche Esempio
Di seguito vedremo come mettere in pratica i concetti sopra esposti, analizzando qualche esempio con gli stream di Redis.
Creazione di un channel
Dato che Redis non permette la creazione di channel vuoti, possiamo adoperare uno stratagemma che consiste nel creare un channel contenente un dato di tipo null
.
xadd topic_html* create-channel null
Con questo comando, abbiamo appena creato un channel chiamato topic_html.
Aggiunta di un messaggio
Per aggiungere un messaggio al canale, usiamo il messaggio XADD
, come mostrato di seguito:
xadd topic_html * msg1-vito "Ciao a tutti."
xadd topic_html * msg2-vito "Leggete il nuovo articolo sui Redis Stream."
msg1-vito e msg2-vito
sono degli identificativi che assegnamo al nostro messaggio.
Lettura di un messaggio
Per leggere un messaggio da un canale, dovremo invece usare il comando XREAD
:
xread BLOCK 100 STREAMS topic_html $
topic_html è il nome del channel di cui stiamo andando a recuperare i primi 100 messaggi, e il simbolo $
viene usato come identificativo speciale per richiedere i messaggi da un channel.
IoT e stream
Per concludere questa panoramica sugli stream di Redis, possiamo aggiungere che uno dei migliori campi in cui essi possono trovare applicazione è quello dell'Internet of Things (IoT). Il fatto che gli stream siano stati pensati per poter essere impiegati in differenti sistemi, li rendono una valida alternativa tecnologica a tutte quelle tecnologie già largamente adoperate in questo settore. Per chi non lo sapesse, infatti, Redis è stato pensato per poter girare anche in sistemi come Raspberry Pi, oltre che in sistemi basati su processori ARM. Ciò lo rende un sistema efficace ed in grado di interfacciarsi con la maggior parte dei dispositivi disponibili sul mercato.