2015-10-28 12 views
6

TL; DR Sto cercando un modo per memorizzare, incrementare e recuperare intervalli di conteggi di eventi per minuto.Come incrementare il valore di un set ordinato redis

Sto cercando una soluzione per la creazione di un numero di volte in aumento in redis. Sto cercando di archiviare i conteggi al minuto. Il mio obiettivo è essere in grado di cercare un intervallo di tempo e ottenere i valori. Quindi per instnace se si è verificato un evento per una chiave specifica 30 volte al minuto. Vorrei fare qualcosa come zrange e ottenere i loro valori chiave. Spero anche di usare qualcosa come zincrby per incrementare il valore. Ovviamente ho guardato un set ordinato che sarebbe sembrato perfetto, fino a quando ho realizzato che posso solo eseguire una scansione di intervallo sul punteggio e non sul valore. La soluzione ottimale sarebbe utilizzare il numero di minuti come punteggio e quindi utilizzare il valore nel set ordinato come il numero di eventi per quel minuto. Il problema a cui mi sono imbattuto è che lo zero zinco incrementa solo il punteggio e non il valore. Non ero in grado di trovare un modo per incrementare il valore atomicamente. Ho anche esaminato una hashmap usando il minuto corrente come chiave e il numero di eventi come valore. Sono stato in grado di incrementare il valore usando hincrby ma il problema è che non supporta il recupero di un intervallo di chiavi.

Qualsiasi aiuto sarebbe apprezzato.

risposta

4

Sai, giusto una domanda ha già una risposta. E tu dici già di redis come risolvere il tuo problema:

  1. Utilizzare ZSET - chiave come ora e valore come contatore.
  2. Utilizzare HSET - chiave come ora e valore come contatore.
  3. Utilizzare string keys - nome della chiave come ora e valore come contatore.

Perché solo questi casi - siccome di soli queste strutture (ZSET, HSET e string keys) dispone di metodi atomiche per aumentare i valori.

Così actualy:

  1. Si dovrebbe fare proprio scelta sulla struttura dei dati.
  2. Risolvi il problema con la selezione dei dati.

La prima domanda è il compromesso tra memoria e perfomance. Dalla tua domanda non è necessario avere alcun tipo se l'ordinamento in modo che i set ordinati non siano la soluzione migliore - consumare molta memoria e la complessità temporale ZINCRBY è O (log (N)) piuttosto è O (1). Quindi dovremmo scegliere tra hash e chiavi di stringa. Si prega di guardare a question and answer riguardo all'ottimizzazione della memoria giusta in redis - secondo questo penso che dovresti usare gli hash come tipo di dati per la tua soluzione.

La seconda domanda è comune per qualsiasi tipo di struttura di dati, perché di tutti i tipi non contiene le funzioni select by name o analogiche. E potremmo usare HMGET o LUA scripting per risolvere questo problema. In ogni caso questa soluzione avrebbe una complessità temporale O (n).

Ecco campione con Jedis (`m non un programmatore Java, dispiace per eventuali errori):

int fromMinute = 1; 
int toMinute = 10; 

List<String> list = new ArrayList<String>(); 
for(int i = fromMinute ; i < toMinute ; i++) { 
    list.add(i.toString()); 
} 

Jedis jedis = new Jedis("localhost"); 
List<String> values = jedis.hmget("your_set_name", list); 

Questa soluzione è atomico, veloce, ha il tempo di complessità O (n) e consumare la memoria il meno possibile in redis.

+0

Grazie per le informazioni !! Sono arrivato quasi alla stessa conclusione, ma non ho pensato all'hmget per ottenere l'elenco delle chiavi. Stavo guardando hscan e mi stavo quasi odiando doverlo fare. Penso che questa sia una soluzione eccellente !! Ho anche trovato un progetto per il nodo che ha una soluzione molto simile che sto per imitare. Utilizza le hashmap per creare le serie temporali depennate dalle granularità di Minuto/Ora/Secondo ecc. –

+1

Hai dimenticato di dare credito alla libreria dei nodi http://blog.apiaxle.com/post/storing-near-realtime-stats-in- Redis / –