2

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

第一个记分牌是我使用列表的“最新分数” LPUSH。第二个是我在ZADD命令中使用排序列表的历史最高分。

我在执行“本周的高分”时遇到了麻烦。我在想我应该使用另一个排序列表使用ZADD一个EXPIRE集合一周。一切正常,但在列表第一次过期后,它将继续永远添加到新列表中。

是否有 redis 命令可以自动续订过期?(我已经寻找了几个小时的答案,但答案似乎是否定的)。我得出的结论是,我需要以编程方式执行此操作。在使用 set 的函数调用期间,我可以检查是否TTL为 -1 并在那里重置它。这是最佳实践吗?我在某处错过了一个聪明的把戏吗?我需要关注额外的数据库请求吗?

- 编辑 -

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

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

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

这对我来说“感觉”是对的,但我是 redis 的新手,所以希望能就这项技术或任何其他解决问题的方法进行一些讨论。

4

1 回答 1

1

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

  1. “过去 7 天”
  2. “一年中的一周”
  3. “这周从周日开始,到周六结束”

最简单的实现是 2 和 3。您指定一个集合,其中包括在其键名中的开始日期/时间,使用一周的过期时间。然后,您只需在客户端确定您想要哪一天并获取数据。

例如 zadd scoreboard:weekly:03:March:2013 1 "bob"

然后在接下来的一周,您的键名将是 zadd scoreboard:weekly:10:March:2013 1 "bob"

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

if (ttl scoreboard:weekly:03:March:2013) == 0: expire scoreboard:weekly:03:March:2013 604800

这样您只需设置一次过期时间,自动过期,并且可以轻松拉出每周记分牌。

您可以使用相同的方法实现滚动周,但您需要转到每日密钥名称并计算要获取的密钥,然后合并它们。您可以使用 zunionstore 执行此操作。

于 2013-03-02T20:16:10.413 回答