2013-08-20 16 views
10

abbiamo il seguente caso d'uso: ogni volta che scade un determinato tasto, dobbiamo ricevere una notifica e fare qualcosa, in base al suo valore. Ma quando si attiva l'evento expired redis, la chiave è già stata rimossa dal db quando proviamo ad accedervi in ​​seguito, cosa ovviamente prevista.Notifiche redis 2.8: Ottieni valore invece di chiave (in scadenza)

Ora c'è un modo per accedere nuovamente alla voce, dopo che è scaduta? Non credo.

Quindi seconda opzione: c'è un modo per dire a redis di pubblicare l'intero oggetto valore invece della sola chiave quando si inviano quegli eventi? Immagino che possa essere aggiunto tramite Lua, ma mi piacerebbe avere un'opzione più semplice, se possibile. Abbiamo anche bisogno di questo comportamento per altri eventi, fondamentalmente abbiamo bisogno di tutte le notifiche per pubblicare il valore, non la chiave (potremmo fare un GET una volta che l'evento è stato ricevuto, ma vogliamo aggirare la seconda chiamata, principalmente per avere un processo atomico , poiché il valore potrebbe essere cambiato tra la pubblicazione dell'evento e il GET per recuperare il valore).

Spero sia comprensibile. Forse non possiamo vedere l'ovvio, quindi grazie in anticipo!

+0

Redis 2.8 è ancora un candidato di rilascio finora. Se hai bisogno di controllo sulle notifiche di scadenza delle chiavi, probabilmente sarebbe meglio implementarle esplicitamente (senza alcuna dipendenza da 2.8). Vedi http://stackoverflow.com/questions/11810020/how-to-handle-session-expire-basing-redis/11815594#11815594 –

+2

Bene che 2.8 è ancora RC non è il problema. Il problema è che Redis pubblica eventi con la chiave, anziché il valore della voce. E poiché abbiamo bisogno di questo comportamento per tutte le notifiche, anche 2.6. quelli, abbiamo bisogno di un modo per dire a Redis di darci l'intero oggetto nel momento in cui è stato attivato l'evento, invece della chiave. –

+1

Vorrei ancora usare una soluzione basata su zset –

risposta

25

La funzione collegata a Eli consente di ascoltare quando scade una chiave. Tuttavia, non ti dà il valore della chiave. Inoltre, in base al problema del github archiviato, non sembra che ci si possa aspettare che questa funzione venga creata in qualsiasi momento, se possibile (https://github.com/antirez/redis/issues/1876). La soluzione che utilizzo è creare una speciale chiave di scadenza "shadow" collegata alla chiave in cui si ha un valore reale.

Quindi diciamo che avete una chiave chiamata testkey e ha un valore intero di 100. Inoltre, la chiave scadrà dopo 10 secondi, a quel punto si desidera ottenere il valore della chiave. (Forse stavi incrementando la chiave durante i 10 secondi che esisteva).

Per prima cosa è necessario impostare l'ascolto per gli eventi dello spazio delle chiavi.In particolare, si desidera ascoltare gli eventi expired. Puoi farlo dalla tua configurazione o usare il comando config set in redis. (Vedi qui per ulteriori informazioni: http://redis.io/topics/notifications)

CONFIG SET notify-keyspace-events Ex 

Ora è possibile iscriversi a una speciale keyevent canale in cui vi verrà notificato che la chiave è scaduto.

SUBSCRIBE [email protected]__:expired 

Il formato del canale di sottoscrivere è [email protected]<db>__:<eventName>. Nel nostro esempio stiamo assumendo che stiamo lavorando con il database predefinito 0 e vogliamo ascoltare l'evento expired.

Quando lo testkey scade, verrà visualizzato un messaggio nel canale __keyevent__ in cui il messaggio è il nome della chiave scaduta. Ovviamente a questo punto la chiave è sparita quindi non possiamo più accedere al valore! La soluzione è usare una chiave di scadenza speciale.

Quando si crea il testkey, creare anche una speciale chiave "shadow" in scadenza (non scadere l'attuale testkey). Per esempio:

SET testkey 100 
SET shadowkey:testkey "" EX 10 

Ora nel canale [email protected]__:expired si otterrà un messaggio che indica che la chiave shadowkey:testkey scaduto. Prendi il valore del messaggio (che è il nome della chiave), dividi i due punti (o qualsiasi altro separatore che decidi di usare), quindi ottieni manualmente il valore della chiave e cancellalo.

// set your key value 
SET testkey 100 
//set your "shadow" key, note the value here is irrelevant 
SET shadowkey:testkey "" EX 10 
// Get an expiration message in the channel [email protected]__:expired 
// Split the key on ":", take the second part to get your original key 
// Then get the value and do whatever with it 
GET testkey 
// Then delete the key 
DEL testkey 

Si noti che il valore del Shadowkey non viene utilizzato in modo che si desidera utilizzare il valore più piccolo possibile che secondo questa risposta (Redis store key without a value) è una stringa vuota "". È un po 'più di lavoro da configurare, ma il sistema di cui sopra fa esattamente ciò di cui hai bisogno. Il sovraccarico è un paio di comandi extra per recuperare ed eliminare effettivamente la tua chiave più il costo di archiviazione di una chiave vuota.

+0

Bella idea anche se raddoppia l'impronta di quel valore . Un possibile tweak memorizza solo il valore nel tasto "shadow" e usa il tasto attuale solo per scopi di scadenza. –

+1

@ItamarHaber Il tasto shadow non memorizza il valore attuale. Infatti, in base a questa risposta (http://stackoverflow.com/questions/25557250/redis-store-key-without-value) il valore della chiave shadow dovrebbe essere solo una stringa vuota (nel mio esempio ho dato un valore di "1" ma ora lo ha aggiornato). Quindi l'unico overhead è quello di una chiave extra (non dovresti duplicare il tuo valore) – Sarus

+0

Right - read it downside :) –

1

Se si è su 2.8, è possibile provare this new feature (indicato anche allo this page). E 'sicuramente instabile e non sembra ben testato, ma se siete in 2,8 ogni caso ...

intro breve dalla pagina problema:

Una caratteristica interessante nei database con i dati di valori-chiave modello (Redis non si adatta perfettamente a questa definizione in quanto i valori sono dati complessi struttura, ma il livello esterno di Redis è sicuramente un valore-chiave aziendale) è la possibilità di iscriversi in qualche modo allo streaming degli eventi rivolti a un dato chiave.

Per esempio io possa essere interessato a vedere quando il foo chiave viene eliminato o modificato in qualche modo, o per ottenere i nomi di tutte le chiavi di un scadono set (utilizzando il comando expire) che Redis è sfrattando dal il set di dati perché il loro tempo di vita è sceso a zero.

Questa funzione è stata richiesta molte volte dalla base di utenti Redis, tuttavia finora non abbiamo mai raggiunto un punto in cui l'API proposte (compresi proposte fatte da me) sembrava adattarsi bene nel design Redis. Questa richiesta di funzionalità tenterà di descrivere un nuovo design che è estremamente semplice da utilizzare, da implementare e che si adatta bene alla storia di Redis .

Problemi correlati