Redis Update Sorted Set on Key Expire

Oct 13 2020

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

3 TugGrall Oct 13 2020 at 18:43

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.