Redis permette di creare delle chiavi "volatili", ovvero con una durata limitata. Allo scadere del loro tempo di vita, esse non potranno essere più invocate ed i valori ad esse collegate non saranno più recuperabili. Tale meccanismo può sembrare stridente rispetto al concetto di persistenza dei dati tipico dei database, eppure chiavi con una durata limitata nel tempo possono trovare molte applicazioni. Tanto per fare qualche esempio, si pensi a:
- gestione di chiavi di sessione: un client che accede ad un'applicazione viene spesso associato ad una sessione di lavoro identificata da un codice univoco. Considerato che le sessioni hanno durata limitata, una chiave temporanea potrebbe risolvere in automatico il problema della loro invalidazione;
- caching di contenuti: quando si ha bisogno di mantenere contenuti attivi in memoria per un tempo limitato, può essere sufficiente associare ogni informazione ad una chiave di durata limitata;
- messaggi a scadenza: esistono servizi che conservano messaggi usa-e-getta che si "autodistruggono" in un tempo limitato per poter inviare informazioni sensibili che non restino in memoria per sempre. Anche in questo caso l'impiego della scadenza delle chiavi offre in automatico il meccanismo.
Alcune di queste idee verranno sfruttate nel seguito della guida per svolgere degli esempi pratici, ma per il momento ci limitiamo ad indagare il funzionamento delle chiavi volatili in Redis.
La parola chiave EXPIRE
Con il comando EXPIRE si può impostare una durata (in secondi) per una chiave esistente:
> SET session_id 12345
> EXPIRE session_id 20
> GET session_id
"12345"
Il timeout è stato impostato a 20 secondi: dopo questo lasso di tempo, la chiave non risulta più esistente:
> GET session_id
(nil)
Esiste anche un altro comando che permette di impostare timeout per le chiavi: è PEXPIRE ed ha un funzionamento identico al precedente, con l'unica differenza che la durata è impostata in millisecondi anzichè in secondi.
Si può inoltre appurare il tempo di vita rimanente di una chiave, misurato in secondi, con TTL (acronimo che sta per Time To Live):
> SET session_id 12345
OK
> EXPIRE session_id 20
(integer) 1
> TTL session_id
(integer) 15
...
> TTL session_id
(integer) 10
...
> TTL session_id
(integer) 7
e dopo la scadenza del timeout:
> TTL session_id
(integer) -2
All'ultima interrogazione, TTL
ha restituito un valore negativo, a significare che la chiave è scaduta. Si noti, però, che questa interpretazione è associabile al solo valore -2, mentre -1 indicherà che a quella chiave non è stata affatto associata una scadenza. Anche per il Time To Live esiste un ulteriore comando, PTTL, della medesima finalità ma che restituisce l'informazione in millisecondi.
Fissare una scadenza con timestamp
Impostare scadenze in secondi e millisecondi talvolta può risultare scomodo. Esistono due comandi che permettono di usare un timestamp (il tempo trascorso dalla mezzanotte del 1° gennaio 1970), che di fatto rappresenta una data: EXPIREAT e PEXPIREAT, che richiedono rispettivamente l'informazione in secondi e millisecondi.
Ecco un esempio:
> SET session_id 12345
OK
> EXPIRE session_id 1521061825
(integer) 1
> TTL session_id
(integer) 103
In questo caso, il timestamp 1521061825 equivale al 14 marzo 2018, ore 21:10 e 25 secondi, e con il comando TTL
abbiamo scoperto che mancavano 103 secondi al suo raggiungimento. Per la conversione timestamp/data e viceversa si possono usare basilari funzioni incluse in qualsiasi linguaggio di programmazione, o ricorrere ai tanti servizi online facilmente individuabili in Rete. In Redis, il comando TIME restituisce il timestamp relativo all'orario del server.
Timeout passati e ripristino della persistenza
La persistenza di una chiave può essere ripristinata con il comando PERSIST. Osserviamo la seguente sessione di lavoro:
> SET valore 3
OK
> TTL valore
(integer) -1
> EXPIRE valore 50
(integer) 1
> TTL valore
(integer) 46
> PERSIST valore
(integer) 1
> TTL valore
(integer) -1
Al suo interno:
- impostiamo la variabile valore a 3;
- invochiamo
TTL
ottenendo un valore -1 in quanto non c'è alcun timeout fissato; - assegniamo un timout di 50 secondi;
- a questo punto il comando
TTL
restituisce un valore maggiore di 0 in quanto la chiave è diventata temporanea e mancano 46 secondi allo scadere; - con il comando
PERSIST
la chiave torna a essere persistente; - all'ultima riga,
TTL
torna a restituire -1 in quanto il timeout non esiste più sulla chiave in virtù della invocazione
aPERSIST
. La chiave quindi non è più temporanea.
Si noti, infine, che i timout possono essere impostati già "scaduti" ossia con un numero di secondi/millisecondi negativo
(per EXPIRE
e PEXPIRE
) o con un timestamp fissato nel passato (per EXPIREAT
e PEXPIREAT
) ma ciò causerà l'immediata cancellazione della variabile.
Questa la dimostrazione con EXPIRE:
> SET numero 45
OK
> EXPIRE numero -1
(integer) 1
> TTL numero
(integer) -2
> GET numero
(nil)
Una volta impostata la variabile a 45, fissiamo con EXPIRE
una scadenza negativa e al primo tentativo di invocare
TTL
otteniamo come risultato -2, vale a dire "timeout scaduto". Con GET
verifichiamo cosa ne è stato di valore e non troviamo più niente: la variabile non esiste più. Con EXPIREAT
otteniamo lo stesso risultato ma per farlo è necessario inserire un timestamp passato:
> SET citta "Roma"
OK
> GET citta
"Roma"
> EXPIREAT citta 1500000
(integer) 1
> TTL citta
(integer) -2
> GET citta
(nil)
Anche in questo caso la chiave viene creata con SET
, trasformata in temporanea con EXPIREAT
ma con un timestamp passato pertanto TTL
non può far altro che rispondere -2 in merito ad essa. La variabile è stata eliminata anche in questo caso come dimostra la chiamata a GET
che ottiene ancora "nil" come risultato.