Redis in due atti: singolare e plurale.
In questi due articoli vedremo come installare una singola instanza Redis, e come si potrà poi estendere per ottenere una configurazione ridondata per aumentarne le performance. Parte 1 di 2.
Redis (Remote Dictionary Server) è un sistema di archiviazione in-memory, open-source, che può essere utilizzato come database, cache o message broker. È particolarmente apprezzato per la sua velocità, poiché tutti i dati vengono memorizzati direttamente nella RAM, consentendo accessi estremamente rapidi rispetto ai tradizionali database basati su disco. Supporta diverse strutture dati come stringhe, liste, insiemi, hash, bitmap, e molti altri, offrendo grande flessibilità per vari casi d'uso.
Dal momento che REDIS permette un accesso estremamente rapido ai dati, è chiaro che il suo utilizzo sia assolutamente mandatory in tutte quelle applicazioni in cui le performance hanno rilevanza (eg. tutte). Vediamo quindi come installare una semplice configurazione Redis single node e come interargi con una piccola applicazione di esempio in python, php e nodejs. Nel prossimo articolo invece estenderemo questa installazione tramite l’uso di redis-sentinel, per avere una configurazione multi node.
Installazione Redis Server
In questo esempio utilizzaremo Debian 12.5 come sistema operativo. Ma con piccole variazioni di sintassi dovreste riuscire ad applicarlo in qualunque altra distribuzione.
Oggigiorno redis è disponibile praticamente in qualunque repository ufficiale (eg. debian, ubuntu) tuttavia quasi sempre le versioni che vengono installate tramite tali report sono molto antiquate. Pertanto tramite i soliti comandi:
apt update
apt install redis redis-server redis-tools -y
vi verrà installata la seguente versione:
ii redis-server 5:7.0.15-1~deb12u1
Mentre avendo l’accortezza di aggiungere prima la chiave gpg ed il repository ufficiale di redis (packages.redis.io):
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sempre con i comandi di installazione riportati sopra si avrà la seguente versione disponibile:
ii redis 6:7.4.0-1rl1~bookworm1
Ovviamente queste versioni valgono nel momento della scrittura di questo articolo, il concetto che deve rimanere però è semplicemente che quando possibile è sempre bene aggiungere il repository ufficiale del software, se disponibile per la distribuzione in uso, in modo da assicurarsi di utilizzare sempre codice aggiornato.
A questo punto l’installazione di redis standard sarà eseguita. Assicuratevi però di abilitare la unit all’avvio del sistema con:
systemctl enable redis-server
e controllate che stia funzionando correttamente con:
root@X:~# systemctl status redis
● redis-server.service - Advanced key-value store
Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; preset: enabled)
Active: active (running) since Fri 2024-09-27 11:03:51 CEST; 20min ago
Docs: http://redis.io/documentation,
man:redis-server(1)
Main PID: 1823453 (redis-server)
Status: "Ready to accept connections"
Tasks: 6 (limit: 4531)
Memory: 3.5M
CPU: 7.680s
CGroup: /system.slice/redis-server.service
└─1823453 "/usr/bin/redis-server 127.0.0.1:6379"
A questo punto potete testare l’effettivo funzionamento tramite due comandi:
redis-cli ping
che dovrà rispondere PONG, qualora il server sia operativo. E soprattutto:
root@X:~# redis-cli
127.0.0.1:6379>
che vi fornirà l’accesso all’interfaccia client del redis-server (come potete vedere dallo screen sopra la porta di default su cui girerà il demone sarà la 6379).
Tramite l’interfaccia redis-cli ad esempio potrete settare un valore di esempio in redis ed estrarlo per leggerlo (di seguito assegnamo e leggiamo il valore 10 ad una variabile chiamata key):
root@X:~# redis-cli
127.0.0.1:6379> set key 10
OK
127.0.0.1:6379> get key
"10"
127.0.0.1:6379>
Bene, a questo punto si può procedere alla personalizzazione del setup.
Configurazione Redis Server
Il file di configurazione di redis si trova in /etc/redis/redis.conf
Fortunatamente aprendolo, vedrete che è estremamente verboso nei commenti alle configurazioni, e questo è un bene visto che quasi tutti noi siamo dei BOFH che piuttosto che aprire un manuale provano qualunque cosa trovata in giro per la rete (sì lo fate tutti e lo sapete).
Naturalmente questa guida non potrà essere estensiva in tutte quelle opzioni, ma ce ne sono almeno un paio che sono assolutamente necessarie e che andremo a vedere.
Impostazione di una password di accesso
Come vedete nell’esempio sopra, tramite redis-cli è stato possibile accedere al redis server e scrivere e leggere un dato, senza effettuare nessun tipo di autenticazione. Questo perchè redis di default non è autenticato. Ovviamente in un contesto di produzione questo non va bene. Pertanto nel suo file di configurazione cercate la variabile
# requirepass foobared
Scommentatela (rimuovendo # all’inizio della stringa) e variatene il valore con una password robusta. A questo punto riavviate il demone. Riprovando ora lo stesso set/get di prima riceveremo questo errore:
root@X:~# redis-cli
127.0.0.1:6379> set key 10
(error) NOAUTH Authentication required.
127.0.0.1:6379> get key 10
(error) NOAUTH Authentication required.
127.0.0.1:6379>
Ossia viene richiesta l’autenticazione altrimenti non ci permette di proseguire. Quindi possiamo autenticarci in questo modo:
root@X:~# redis-cli
127.0.0.1:6379> AUTH la-tua-password-impostata-prima
OK
127.0.0.1:6379> set key 10
OK
127.0.0.1:6379> get key
"10"
Ecco che a questo punto possiamo interagire correttamente con redis autenticato.
Snapshot e modalità Append-Only File (AOF)
Di default redis esegui un dump asincrono dei dati su un file nella directory /var/lib/redis. Il file viene denominato dump.rdb.
Tuttavia vi sono casi di applicazioni in cui la persistenza dei dati è chiave. Il che significa che se poco dopo che redis esegue lo snapshot, la macchina crasha, tutte le operazioni eseguite dalla creazione dello snapshot al crash, al successivo ripristino dello snapshot verranno perse. E questo, non sempre ma a volte sì, può rappresentare un problema. Provate ad immaginare ad esempio un ecommerce ad alto traffico, o un applicazione che si occupa di scambi finanziari. Perdere delle transazioni redis in questo contesto può rivelarsi molto grave per l’applicazione (perdita ad esempio di transazioni o di ordinativi).
Per evitare questo scenario entra in gioco l’Append-Only File (AOF) di redis. Tramite questa modalità redis salva in un file scritto in modalità appunto append-only in cui tiene traccia di tutte le operazioni eseguite su redis. In questo modo a seguito di un crash, potrà ricostruire al 100% tutte le transazioni eseguite in memoria, senza perderne nessuna.
L’Append-Only File (AOF) di default è disabilitato, e quando redis viene utilizzato come semplice sistema di cache va benissimo così. Ma quando in redis vengono memorizzati dati chiave per l’applicazione è molto importante abilitarlo poichè fornisce una persistenza quasi in tempo reale con un compromesso assolutamente accettabile tra performance e sicurezza dei dati, risultando utile per applicazioni in cui la perdita anche minima di dati non è tollerabile.
L’abilitazione è molto semplice, sempre considerando il file di configurazione di cui sopra, cercare la variabile appendonly ed impostarla su yes:
appendonly yes
Riavviando il server redis e lasciando tutte le altre impostazioni di default trovete che verrà creata questa directory:
/var/lib/redis/appendonlydir/
con all’interno tutti i file salvati in modo sincrono da redis di tutte le operazioni eseguite.
Come interrogare redis server da codice
Eseguire il medesimo set/get che abbiamo provato prima da redis-cli da codice, è estremamente semplice, poichè tutti i principali linguaggi oggi forniscono delle libreria per interfacciarsi con redis in modo stabile e sicuro. Alcuni esempi di seguito.
# PYTHON
#
# Assicurarsi di aver installato python3-redis tramite apt:
# apt-get install python3-redis
#
# Salva questo file come test.py e lancialo con:
# python3 test.py
import redis
# Connessione a Redis server locale
r = redis.Redis(host='localhost', port=6379, db=0, password='la-tua-password-impostata-prima')
# Impostazione della chiave
r.set('key', 10)
# Recupero del valore della chiave
value = r.get('key')
print(int(value)) # Output: 10
# PHP
#
# Assicurati di aver installato predis tramite composer:
# composer require predis/predis
# Salva questo file come test.php e lancialo con:
# php test.php
<?php
require 'vendor/autoload.php';
$client = new Predis\Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => 'la-tua-password-impostata-prima'
]);
// Impostazione della chiave
$client->set('key', 10);
// Recupero del valore della chiave
$value = $client->get('key');
echo $value; // Output: 10
# NODEJS
#
# Assicurati di installare il pacchetto redis con npm:
# npm install redis
#
# Salva questo file come app.js e lancialo con:
# node app.js
const redis = require('redis');
// Connessione a Redis server locale
const client = redis.createClient({
url: 'redis://:la-tua-password-impostata-prima@127.0.0.1:6379'
});
client.on('error', (err) => console.error('Redis error:', err));
client.connect().then(async () => {
// Impostazione della chiave
await client.set('key', 10);
// Recupero del valore della chiave
const value = await client.get('key');
console.log(value); // Output: 10
client.quit(); // Chiusura della connessione
});
Siamo giunti al termine di questo articolo introduttivo di Redis. Spero possa esserti utile come base di partenza per integrare l’uso di redis nella tua prossima applicazione. Nella prossima puntata vedremo come estendere questa configurazione passando da un server redis in singola installazione ad un server redis multi nodo.