我正在构建一个应用程序,其中我需要三个记分牌,这些记分牌将通过排序的集合和列表来实现。该应用程序在redis客户端上使用node_redis(https://github.com/mranney/node_redis)模块在node.js上运行。

第一个计分板是“最新分数”,我使用的是列表和LPUSH。第二个是历史最高分,我正在使用ZADD命令的排序列表。

我在实现“本周高分”时遇到了麻烦。我当时想我应该使用另一个使用ZADDEXPIRE设置一周的排序列表。一切正常,但是列表第一次过期后,它将永远永远添加到新列表中。

是否有redis命令使到期自动续订? (我已经搜索了几个小时的答案,但答案似乎没有)。我得出的结论是,我需要以编程方式进行此操作。在使用该集合的函数调用过程中,我可以检查TTL是否为-1,然后在其中重置它。这是最佳做法吗?我在某处缺少聪明的把戏吗?我是否需要担心额外的数据库请求?

- 编辑 -

我已经在twitter https://twitter.com/redsmin/status/302177241167691777上回答了这个问题

建议的解决方案(如果我理解正确的话)是将EXPIREAT命令与每个ZADD一起使用

expireat myscoreboard {{timestamp of the end of the week}}
zadd myscoreboard 1 "one"

这种“感觉”对我来说是正确的,但是我是Redis的新手,因此希望对这种技术或解决问题的任何其他方式进行一些讨论。

最佳答案

这取决于您如何定义“一周”。有几种使用它的方法,例如:

  • “过去7天”
  • “本周最佳”
  • “这周从星期日开始,到星期六结束”

  • 最简单的实现是2&3。
    您可以指定一个密钥集,其中包含一个开始使用的日期/时间,密钥有效期为一周。然后,您只需在客户端上确定要获取哪一天的数据即可。

    例如
    zadd计分板:每周:03:3月:2013 1“bob”

    然后,下周您的键名将为
    zadd计分板:每周:10:3​​月:2013 1“bob”

    首次创建密钥时,您要设置过期,仅此而已。无需每次都重新设置。伪代码如下:

    如果(ttl记分板:每周:03:3月:2013)== 0:
    过期记分牌:每周:03:3月:2013 604800

    这样,您只需设置一次到期,就可以自动到期,并且可以轻松获取每周记分板。

    您可以使用相同的方法实现滚动周,但是您需要使用每日密钥名称并计算要获取的密钥,然后将它们合并。您可以使用zunionstore做到这一点。

    09-26 18:35