2012-12-12 13 views
6

Sto tentando di archiviare gli oggetti multimediali e renderli recuperabili da un determinato intervallo di tempo tramite i redis. Ho scelto un tipo di dati set ordinato per farlo. Sto aggiungendo elementi come:Garantire l'unicità per un set ordinato in redis

zAdd: key: media:552672 score: 1355264694 
zAdd: key: media:552672 score: 1355248565 
zAdd: key: media:552672 score: 1355209157 
zAdd: key: media:552672 score: 1355208992 
zAdd: key: media:552672 score: 1355208888 
zAdd: key: media:552672 score: 1355208815 

Dove chiave è unica per l'id posizione media è stata presa al e il punteggio è l'ora di creazione dell'oggetto multimediale. E il valore è un json_decode dell'oggetto multimediale.

Quando vado a recuperare utilizzando zRevRangeByScore, occasionalmente ci saranno voci duplicate. Sto essenzialmente usando Redis come buffer per un'API esterna, se gli utenti fanno la stessa chiamata API due volte con X secondi, quindi recupererò i risultati dalla cache, altrimenti lo aggiungerò alla cache, non controllando per vedere se esiste già a causa della definizione di un set che non contiene duplicati. Possibili problemi noti: Se l'oggetto multimediale modifiche di attributo tra la cache verrà visualizzato come un duplicato

C'è un modo migliore per archiviare questo tipo di dati senza fare controlli sul lato client Redis?

TLDR; Qual è il modo migliore per archiviare e recuperare oggetti in Redis in cui è possibile selezionare un intervallo di oggetti per data e ora e assicurarsi che siano univoci?

risposta

23

Lets assicuriamo che stiamo parlando delle stesse cose, ecco la terminologia per Redis allineati set:

ZADD key score member [score] [member] 
summary: Add one or more members to a sorted set, or update its score if it already exists 
  • key - il 'nome' della ordinato set
  • score - il punteggio (nel nostro caso un timestamp)
  • member - la stringa il punteggio è associato a
  • Un insieme ordinato ha molti membri, ciascuno con un punteggio

Sembra che tu stia utilizzando una stringa codificata JSON dell'oggetto come membro. Il membro è ciò che è unico in un insieme ordinato. Come dici tu, se l'oggetto cambia, verrà aggiunto come nuovo membro al set ordinato. Questo probabilmente non è quello che vuoi.

Un insieme ordinato è il modo per memorizzare i dati in base al timestamp, ma il membro memorizzato nell'insieme è solitamente un "puntatore" a un altro tasto in Redis.

Dalla tua descrizione Penso che si desidera questa struttura dati:

  • Un ordinati in impostata la memorizzazione di tutti i media da parte timestamp creato
  • Una stringa o hash per ciascun supporto unici

mi raccomando la memorizzazione gli oggetti multimediali in un hash in quanto ciò consente una maggiore flessibilità. Esempio:

# add some members to our sorted set 
redis 127.0.0.1:6379> ZADD media 1000 media:1 1003 media:2 1001 media:3 
(integer) 3 
# create hashes for our members 
redis 127.0.0.1:6379> HMSET media:1 id 1 name "media one" content "content string for one" 
OK 
redis 127.0.0.1:6379> HMSET media:2 id 2 name "media two" content "content string for two" 
OK 
redis 127.0.0.1:6379> HMSET media:3 id 3 name "media three" content "content string for three" 
OK 

Ci sono due modi per recuperare i dati memorizzati in questo modo.Se è necessario ottenere membri all'interno di intervalli di data/ora specifici (ad esempio: ultimi 7 giorni) sarà necessario utilizzare ZREVRANGEBYSCORE per recuperare i membri, quindi scorrere tra quelli per recuperare ogni hash con HGETALL o simile. Vedere pipelining per vedere come è possibile eseguire il ciclo con una chiamata al server.

redis 127.0.0.1:6379> ZREVRANGEBYSCORE media +inf -inf 
1) "media:2" 
2) "media:3" 
3) "media:1" 
redis 127.0.0.1:6379> HGETALL media:2 
1) "id" 
2) "2" 
3) "name" 
4) "media two" 
5) "content" 
6) "content string for two" 

Se si desidera solo per ottenere gli ultimi membri n (o ad esempio: 10 più recente al più recente 100 °) è possibile utilizzare SORT per ottenere elementi. Vedere la sintassi sort documentation per la sintassi e come recuperare diversi campi hash, limitare i risultati e altre opzioni.

redis 127.0.0.1:6379> SORT media BY nosort GET # GET *->name GET *->content1) DESC 
1) "media:2" 
2) "media two" 
3) "content string for two" 
4) "media:3" 
5) "media three" 
6) "content string for three" 
7) "media:1" 
8) "media one" 
9) "content string for one" 

NB: l'ordinamento un hash ordinati secondo il punteggio (BY nosort) funziona solo da Redis 2.6.

Se si pianifica di ottenere supporti per l'ultimo giorno, settimana, mese, ecc. Si consiglia di utilizzare un set ordinato separato per ognuno e utilizzare ZREMRANGEBYSCORE per rimuovere i vecchi membri. È quindi possibile utilizzare semplicemente SORT su questi set ordinati per recuperare i dati.

+0

Grazie per questo, stavo cercando una cosa esatta. Una domanda veloce: ho una situazione in cui non voglio duplicati, quindi li sto controllando nel mio set ordinato e poi aggiungendoli e creando l'hash. Volevo solo chiederti se è eccessivo? –

Problemi correlati