在 Redis 排序集中按时间戳管理旧元素

Ave*_*yan 1 php redis

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

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

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

谢谢。

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

The*_*ill 5

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

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

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

具体来说: Sorted-Set-A:按照玩家现在的排名。

Sorted-Set-B:使用时间戳作为该人进入队列的时间,存储他们的用户 ID。换句话说,当您使用他们的等级和 ID 将它们添加到 SetA 时,您会使用时间戳和 ID 将它们添加到 SetB。

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

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

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

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