Redis:在列表或排序集中扇出新闻源?

时间:2014-03-13 10:27:49

标签: redis

我通过以下方式使用Redis缓存扇出新闻源:

每个Feed活动都是一个键/值,例如activity:id,其中值是数据的JSON字符串。

每个新闻Feed目前都是一个列表,关键是feed:user:user_id,列表中包含相关活动的键。

检索我使用的新闻Feed,例如:'排序Feed:用户:user_id by nosort get * limit 0 40'

我考虑将Feed更改为分数集,其中分数是活动的时间戳,这样Feed总是按时间排序。

由于排序集的时间复杂性,我读了http://arindam.quora.com/Redis-sorted-sets-and-lists-Pertaining-to-Newsfeed建议使用列表,但是通过继续使用列表我必须处理插入顺序, 插入过去的故事需要遍历列表并找到要推送的正确索引。 (这可能会导致分布式环境中出现新问题。)

我应该继续使用列表还是去排序集?

有没有办法立即从排序集中检索新闻源(就像列表的sort ... get *命令一样),或者它必须是zrange然后迭代结果并获取每个值?

1 个答案:

答案 0 :(得分:4)

是的,排序集非常快且功能强大。与SORT操作相比,它们似乎更符合您的要求。时间复杂性经常被误解。 O(log(N))非常快,并且可以很好地扩展。我们将它用于一个有序集合中的数千万成员。检索和插入是亚毫秒级。

使用ZRANGEBYSCORE key min max WITHSCORES [LIMIT offset count]获取结果。

根据您将时间戳存储为“得分”的方式,ZREVRANGEBYSCORE可能会更好。

关于时间戳的一个小注释:不需要小数部分的排序集SCORES应该使用15位或更少。所以SCORE必须保持在-999999999999999到999999999999999的范围内。注意:存在这些限制是因为Redis服务器实际上将得分(浮点数)存储为内部的redis-string表示。

因此我建议使用此格式,转换为Zulu Time: - 20140313122802以获得第二精度。您可以为100ms精度添加1位数,但如果 ,则不需要精确度损失。顺便说一句,它仍然是一个浮动64,因此在某些情况下精度损失可能会很好,但是你的情况符合“完美精度”范围,所以这就是我推荐的。

如果您的数据在10年内到期,您还可以跳过三个第一位数字(CCYY的CCY),以达到.0001秒精度。

我建议使用负分数,因此您可以使用更简单的ZRANGEBYSCORE代替REV。您可以使用 -inf 作为起始分数(减去无穷大)和LIMIT 0 100来获得前100名结果。

两个排序集members (或'keys'但由于排序集本身也是一个关键字,这是不明确的)可能共享一个score,这是不问题,相同score内的结果是按字母顺序排列的。

希望这有帮助,TW

聊天后编辑

OP希望从不同的密钥(ZSET / GETSET / HGET密钥)收集数据(使用HSET)。 JOIN可以为您做到这一点,ZRANGEBYSCORE不能。 执行此操作的首选方法是使用简单的Lua脚本。 Lua脚本在服务器上执行。在下面的示例中,为了简单起见,我使用EVAL,在制作中,您可以使用SCRIPT EXISTSSCRIPT LOADEVALSHA。大多数客户端库都内置了一些簿记逻辑,因此您不必每次都上载脚本。

这是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

你像这样使用它(原始示例,未编入性能代码)

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

结果:

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