Redis
 sql >> Base de Dados >  >> NoSQL >> Redis

Redis:distribua feeds de notícias em lista ou conjunto ordenado?


Sim, conjuntos ordenados são muito rápidos e poderosos. Eles parecem uma combinação muito melhor para seus requisitos do que SORT operações. A complexidade do tempo é muitas vezes mal compreendida. O(log(N)) é muito rápido e escala muito bem. Nós o usamos para dezenas de milhões de membros em um conjunto classificado. A recuperação e a inserção são sub-milissegundos.

Use ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count] para obter seus resultados.

Dependendo de como você armazena os timestamps como 'pontuações', ZREVRANGEBYSCORE pode ser melhor.

Uma pequena observação sobre os timestamps:Conjunto ordenado SCORES que não precisam de uma parte decimal devem usar 15 dígitos ou menos. Portanto, o SCORE deve permanecer no intervalo -999999999999999 a 999999999999999. Nota:Esses limites existem porque o servidor Redis realmente armazena a pontuação (float) como uma representação de cadeia de redis internamente.

Portanto, recomendo este formato, convertido para Zulu Time:-20140313122802 para segunda precisão. Você pode adicionar 1 dígito para precisão de 100 ms, mas não mais se você não quer perda de precisão. A propósito, ainda é um float64, então a perda de precisão pode ser boa em alguns cenários, mas seu caso se encaixa na faixa de 'precisão perfeita', então é isso que eu recomendo.

Se seus dados expirarem em 10 anos, você também poderá pular os três primeiros dígitos (CCY de CCYY), para obter uma precisão de 0,0001 segundo.

Sugiro pontuações negativas aqui, para que você possa usar o ZRANGEBYSCORE mais simples em vez do REV 1. Você pode usar -inf como a pontuação inicial (menos infinito) e LIMIT 0 100 para obter os 100 melhores resultados.

Dois conjuntos ordenados members (ou 'keys' mas isso é ambíguo, pois o conjunto classificado também é uma chave em si) pode compartilhar uma score , isso não é problema, os resultados dentro de uma score idêntica são alfabéticos.

Espero ter ajudado, tw

Editar após o bate-papo

O OP queria coletar dados (usando um ZSET ) de diferentes chaves (GET /SET ou HGET /HSET chaves). JOIN pode fazer isso por você, ZRANGEBYSCORE não pode. A maneira preferida de fazer isso é um script Lua simples. O script Lua é executado no servidor. No exemplo abaixo eu uso EVAL para simplificar, na produção você usaria SCRIPT EXISTS , SCRIPT LOAD e EVALSHA . A maioria das bibliotecas de cliente tem alguma lógica de contabilidade integrada, portanto, você não carrega o script toda vez.

Aqui está um 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

Você usa assim (exemplo bruto, não codificado para desempenho) :
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

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