Redis
 sql >> Database >  >> NoSQL >> Redis

Redis:fan out i feed di notizie nell'elenco o in un set ordinato?

Sì, i set ordinati sono molto veloci e potenti. Sembrano soddisfare molto meglio le tue esigenze rispetto a SORT operazioni. La complessità del tempo è spesso fraintesa. O(log(N)) è molto veloce e si adatta bene. Lo usiamo per decine di milioni di membri in un set ordinato. Il recupero e l'inserimento sono inferiori al millisecondo.

Usa la chiave ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count] per ottenere i tuoi risultati.

A seconda di come memorizzi i timestamp come "punteggi", ZREVRANGEBYSCORE potrebbe essere migliore.

Una piccola osservazione sui timestamp:set ordinato SCORES che non necessitano di una parte decimale dovrebbero utilizzare 15 cifre o meno. Quindi il SCORE deve rimanere nell'intervallo da -999999999999999 a 9999999999999999. Nota:questi limiti esistono perché il server Redis memorizza effettivamente il punteggio (float) come rappresentazione di una stringa redis internamente.

Consiglio quindi questo formato, convertito in Zulu Time:-20140313122802 per la seconda precisione. Puoi aggiungere 1 cifra per una precisione di 100 ms, ma non di più se non vuoi perdere in precisione. A proposito, è ancora un float64, quindi una perdita di precisione potrebbe andare bene in alcuni scenari, ma il tuo caso rientra nell'intervallo di "precisione perfetta", quindi è quello che consiglio.

Se i tuoi dati scadono entro 10 anni, puoi anche saltare le prime tre cifre (CCY di CCYY), per ottenere una precisione di .0001 secondi.

Suggerisco punteggi negativi qui, quindi puoi usare il più semplice ZRANGEBYSCORE invece di REV uno. Puoi usare -inf come punteggio iniziale (meno infinito) e LIMIT 0 100 per ottenere i primi 100 risultati.

Due set ordinati di members (o 'keys' ma questo è ambiguo poiché l'insieme ordinato è anche una chiave in sé) può condividere un score , non c'è problema, i risultati all'interno di un identico score sono alfabetici.

Spero che questo aiuti, TW

Modifica dopo la chat

L'OP voleva raccogliere dati (usando un ZSET ) da chiavi diverse (GET /SET o HGET /HSET chiavi). JOIN può farlo per te, ZRANGEBYSCORE non posso. Il modo preferito per farlo è un semplice script Lua. Lo script Lua viene eseguito sul server. Nell'esempio seguente utilizzo EVAL per semplicità, in produzione dovresti usare SCRIPT EXISTS , SCRIPT LOAD e EVALSHA . La maggior parte delle librerie client ha una logica di contabilità integrata, quindi non carichi lo script ogni volta.

Ecco un example.lua :

local r={}
local zkey=KEYS[1]
local a=redis.call('zrangebyscore', zkey, KEYS[2], KEYS[3], 'withscores', 'limit', 0, KEYS[4])
for i=1,#a,2 do
  r[i]=a[i+1]
  r[i+1]=redis.call('get', a[i])
end
return r

Lo usi in questo modo (esempio grezzo, non codificato per le prestazioni) :

redis-cli -p 14322 set activity:1 act1JSON
redis-cli -p 14322 set activity:2 act2JSON
redis-cli -p 14322 zadd feed 1 activity:1
redis-cli -p 14322 zadd feed 2 activity:2 

redis-cli -p 14322 eval '$(cat example.lua)' 4 feed '-inf' '+inf' 100

Risultato:

1) "1"
2) "act1JSON"
3) "2"
4) "act2JSON"