我如何在Redis中实现临时领导字?

我如何在Redis中实现临时领导字?,redis,Redis,在Redis中,实现带有排序集的记分板是很简单的,但是我不确定如何实现带有滚动时间窗口(即30/60/90天窗口)的记分板 由于排序集条目没有任何时间成分,实现基于时间的排行榜的最佳方法是什么?这里有两种通用方法(即需要填写详细信息;),您可以仔细考虑: 1) 使用Redis'ZSETs(有序集)的分数性质来存储时间和用户的(?)分数(例如,整数部分可以是时间戳,分数可以是分数)。时间戳部分的范围可以提供时间效果,但为了排序,必须重置历元值的“LSB” 2) 使用不同的引线板,每个滚动窗口一个,

在Redis中,实现带有排序集的记分板是很简单的,但是我不确定如何实现带有滚动时间窗口(即30/60/90天窗口)的记分板


由于排序集条目没有任何时间成分,实现基于时间的排行榜的最佳方法是什么?

这里有两种通用方法(即需要填写详细信息;),您可以仔细考虑:

1) 使用Redis'ZSETs(有序集)的分数性质来存储时间和用户的(?)分数(例如,整数部分可以是时间戳,分数可以是分数)。时间戳部分的范围可以提供时间效果,但为了排序,必须重置历元值的“LSB”

2) 使用不同的引线板,每个滚动窗口一个,并定期或在触摸DB时对其进行维护

第一种方法更简单,但您可能会遇到极端情况(例如浮点数据类型的限制,巨大的ZSET…),因此,如果这是一个问题,您应该考虑预先划分您的排行榜。

编辑-更多示例: 假设您的排行榜的关键是
k
,并且您正在跟踪term1。天真地说,当term1成功时,你会:

ZADD k <epoch> <epoch>:term1
这正是我在第二种方法中的意思,所以是的,你将保留30个密钥(只要记住一旦不再需要它们,就将它们删除/过期)

第一种方法将包括对所有内容使用单个k ZSET。假设你的项数可以上升到10000,考虑下面的伪数,即每个计数和滚动:

escore = ZSCORE k <epoch*>:term1
rscore = ZSCORE k <epoch*>:30d:term1
if (escore == nil):
    escore = <epoch*>

if (rscore == nil):
    rscore = <epoch*>
    for (i=1; i++; i<30):
        rscore += fractional(ZSCORE k <epoch* - i*days>:term1)

ZADD k escore+1/10000 <epoch*> + ':term1'
ZADD k rscore+1/10000 <epoch*> + ':30d:term1'
escore=ZSCORE k:term1
rscore=ZSCORE k:30d:term1
如果(escore==nil):
escore=
如果(rscore==nil):
rscore=

对于(i=1;i++;iI)我不在(1)后面。如果我想显示,例如,“过去30天中使用最多的搜索词”,您能否在(2)中提供ZINCRBY和ZRANGEBYSCORE的示例(如果这些是您会使用的命令?)我需要30个排行榜吗?在我的应用程序中处理搜索词时,我会将30个排行榜全部分为30个排行榜,然后从相应的集合(最早的)中读取?谢谢你的帮助!对像我这样的初学者非常有帮助。谢谢你花时间详细介绍!一个问题——如果每天使用ZUNIONSTORE w/聚合和创建一个新集合,然后在第二天的ZUNIONSTORE创建过程中使用该集合,那么我们不是在人为地增加分数吗?这看起来不像ZUNI的输出ONSTORE应该在另一个ZUNIONSTORE中使用,否则30多天前的计数将永远不会“下降”,因为它们总是会被带入。还是我遗漏了什么?当然,你是对的-我想我的伪编译器需要升级。将编辑答案:)
# initialize today's rolling window if it doesn't exist
if not(EXISTS k:<epoch*>:30d):
    ZUNIONSTORE k:<epoch*>:30d 29 k:<epoch*>-1d ... k:<epoch*>-29d AGGREGATE SUM

rscore = ZSCORE k:<epoch*>:30d term1
if (rscore == nil):
    rscore = 0

ZADD k:<epoch*>:30d rscore+1 term1
escore = ZSCORE k <epoch*>:term1
rscore = ZSCORE k <epoch*>:30d:term1
if (escore == nil):
    escore = <epoch*>

if (rscore == nil):
    rscore = <epoch*>
    for (i=1; i++; i<30):
        rscore += fractional(ZSCORE k <epoch* - i*days>:term1)

ZADD k escore+1/10000 <epoch*> + ':term1'
ZADD k rscore+1/10000 <epoch*> + ':30d:term1'