1

你在redis中有一个排序集A,你不时向它添加新元素,它们按等级排序,例如你也有一个排序集B。

有没有办法检查集合 A 中是否有元素已经存在超过 20 秒,然后将它们移动到排序集合 B

因为这种检查操作非常频繁,而且列表可能非常大,遍历集合中的每个元素并不是一个好的解决方案。需要最快的。

谢谢。

更新:这就是我想要做的:基本上这个想法是,想象你有某种游戏服务器,当他们提出战斗请求时可以匹配对手。当前的设计是每个请求都进入集合,并且排名/分数是玩家排名。因此,列表中每 2 个彼此靠近的玩家都是完美匹配。每 5 秒左右调用一个脚本,从集合顶部拉出 50 行,并 2 对 2 匹配它们(并删除它们)。这工作正常,我认为这是一个非常快速的工作解决方案。但随后创建机器人(AI)玩家的想法出现了。这样当玩家在que中等待太久时,他就会与机器人(AI)玩家匹配。而且我无法找到一种方法来查看“谁等待太久”基本上可能整个想法都是错误的..所以欢迎任何更好的想法:

4

1 回答 1

6

如果排序集中的分数是 unix 时间戳,则可以使用zrange从集 A 中获取最旧的 NN 项。然后您可以进行检查,将符合条件的条目添加到集 B,然后从集 A 中删除它们。

如果您在集合 A 中的评分不是基于时间戳,那么您将不得不完全迭代您的集合 A,或者重新考虑您的设计。Redis 键在添加时没有固有的可用时间戳(这对于键中的项目(例如排序集)更是如此),因此它必须是您专门创建和跟踪的东西。也许如果您分享更多关于您在做什么以及为什么我们可以提供更多详细信息的信息。

编辑:根据您对问题的补充,我建议尝试类似于@akonsu 提出的解决方案。

具体来说:Sorted-Set-A:与现在一样按等级排列的玩家。

Sorted-Set-B:使用时间戳作为人进入队列的时间,存储他们的用户 ID。换句话说,当您使用他们的排名和 ID zadd 到 SetA 时,您使用时间戳和 ID 将 zadd 到 SetB。

当您匹配球员时,您将他们从两组中删除。如果您使用 zrange 命令从 SetB 中拉出一组用户以匹配 X 最旧的条目,您将有他们排队的时间,按照他们的条目顺序(如 FIFO)。然后,您在 SetA 上使用 zrange 命令,其排名 +/- 您需要的任何排名范围。如果你得到一场比赛,你可以通过将他们从两组中移除并继续比赛来继续比赛。

如果 SetA 中没有合适的对手,并且他们的时间戳足够老,您可以与 AI 匹配,则将他们从两组中移除并继续前进。

本质上它是用户->时间戳的索引队列。这样做意味着所有用户的排队时间更短,因为您现在按照队列长度的顺序匹配他们。您仍然使用 SetA 根据玩家的排名进行匹配,但现在您正在根据时间进行索引和优先级排序。

具体的实现可能比这更有趣,但作为一个整体策略,我认为这符合你的需要。

于 2013-06-04T17:12:30.170 回答