Redis Update Sorted Set on Key Expire
Ho un server Redis con un insieme di coppie di valori chiave e un insieme ordinato che fornisce un indice delle chiavi di tali coppie di valori chiave.
Le coppie chiave-valore possono entrare in uno stato "completato" ea questo punto dovranno essere eliminate dopo 1 ora. Ciò può essere ottenuto semplicemente impostando una scadenza sui tasti, ma cancellarli dal set ordinato sembra essere più problematico.
Potrei avere un processo che scansiona i set e li aggiorna di tanto in tanto, ma sarebbe bello avere qualcosa di un po 'più pulito.
Non penso che ci sia un modo per attivare qualcosa come una stored procedure alla scadenza o impostare una scadenza sui valori impostati ordinati.
Mi sono perso qualcosa o il manuale è l'unico modo?
Risposte
Hai ragione, non puoi "mettere una scadenza" sul valore impostato ordinato stesso.
Ma puoi lavorare con la chiave principale e catturare l'evento quando si verifica la scadenza. Hai almeno 2 modi per ottenere questo risultato:
- Utilizzo della notifica dello spazio chiave
- Utilizzo di Redis Gears
Notifica spazio chiave
Utilizzando la notifica dello spazio chiave, è possibile acquisire l'evento EXPIRE che invierà un messaggio PUBBLICARE che è possibile consumare.
Lasciatemi spiegare il flusso di base:
Configura notifiche
CONFIG SET notify-keyspace-events Ex
- E : eventi che accadono sui tasti
- x : cattura gli eventi scaduti
Ora il tuo database pubblicherà un evento sul __key*__:*canale.
Quindi puoi costruire un servizio che ascolta questi eventi aggiorna il set (direttamente o indirettamente):
psubscribe __key*__:*
Se hai un'applicazione che ha impostato il valore e la scadenza seguenti
set foo bar EX 5
Dovresti ricevere il seguente messaggio
1) "pmessage"
2) "__key*__:*"
3) "__keyevent@0__:expired"
4) "foo"
Redis Gears
Utilizzando Redis Gears, acquisisci lo stesso evento (si basa anche sulla notifica), ma è più facile scrivere codice direttamente nel tuo database Redis.
Puoi creare un Gears come segue: (questo è uno script Python, sto usando RedisInsight per distribuirlo su Redis)
def process(x):
execute('LPUSH', 'expired:keys', x['value']['key']);
# Capture an expiration event and adds it to 'expired:events' stream
cap = GB('KeysReader')
cap.foreach(lambda x:
execute('XADD', 'expired:events', '*', 'key', x['key']))
cap.register(prefix='*',
mode='sync',
eventTypes=['expired'],
readValue=False)
# Consume new messages from expiration streams and process them somehow
proc = GB('StreamReader')
proc.foreach(process)
proc.register(prefix='expired:*',
batch=100,
duration=1,
trimStream = False)
Guarda la sezione iniziata da cap = GB('KeysReader')
- Questo ascolterà qualsiasi scadenza della chiave
prefix='*'eeventTypes=['expired'] - In caso di scadenza, aggiungerà un messaggio al
'expired:events'Redis Stream utilizzando il comando XADD - Quindi guarda la funzione
proc = GB('StreamReader')che elaborerà i flussi - ogni volta che un nuovo messaggio è nel flusso chiamerà la
process()funzione.
È possibile aggiungere la logica per aggiornare il set ordinato in questa funzione. Nel mio esempio ho appena aggiunto la chiave scaduta a un elenco.
Consentitemi di divergere un po 'dalla tua domanda iniziale.
Sembra che tu stia usando Set ordinato per creare una qualche forma di indicizzazione per i tuoi dati.
Se questo è il caso, dovresti guardare RediSearch, un altro modulo Redis che ti consente di indicizzare i campi hash e quindi utilizzare l'indice per eseguire alcune query avanzate e aggregazioni.
Con RediSearch non è necessario aggiungere alcun codice per gestire l'indice, viene fatto automaticamente dal database e si possono interrogare i campi.
Ti invito a guardare:
- Il modulo RediSearch
- Il RediSearch Guida introduttiva
Scusa se questo non è il motivo per cui stai usando Sorted Set, ma penso che valga la pena controllare in quanto potrebbe semplificare molto il codice dell'applicazione se gestisci l'indice manualmente oggi.