【问题标题】:Redis atomic pop and add to sorted set, BRPOPLPUSH equivalentRedis 原子弹出并添加到排序集,相当于 BRPOPLPUSH
【发布时间】:2018-08-26 07:02:15
【问题描述】:

我有一个 redis 列表“等待”和一个 redis 列表“聚会”。

我有一个长时间运行的进程,可以安全地阻止“等待”列表项的出现,然后将其弹出并使用BRPOPLPUSH 以原子方式将其推送到“聚会”列表中。太棒了。

“等待”列表中的用户重复查询“我是否在“聚会”列表中? .您必须抓取整个列表并循环遍历它。

所以我求助于从 redis 列表切换到 redis 排序集,“分数”作为他们加入“等待”排序集时的 unix 时间戳。我可以在最低分(队列头部的用户)上阻止弹出。使用排序集,如果它们在任一列表中,我可以使用 ZSCORE 来检查 O(1) 时间,所以看起来很有希望。

我怎样才能在有序集合上执行BRPOPLPUSH 的原子等价物? 就像我需要一个神话般的BZRPOPMIN & ZADD= BZRPOPMINZADD。如果进程在这两者之间终止,则用户实际上将从这两个集合中消失。

在redis中查看MULTIEXECtransactions,它们并不是乍一看的样子,它们更像是“管道”,因为我无法得到第一个的结果命令 (BZRPOPMIN) 并将其输入第二个命令 (ZADD)。我非常怀疑将阻止 BZRPOPMIN 也放入 MULTI,我这样做对吗?

【问题讨论】:

  • 我想不出一个好的答案,顺便说一句。一旦你想使用阻塞命令,你就会受到很大的限制,因为 Redis 几乎没有这些命令,而且你失去了用其他命令(事务或脚本)组成原子块的能力。所以一种方法是轮询而不是阻止。更好的建议可能是忽略看起来可怕的 O(n) 并坚持您的原始设计。 Redis 的速度非常快,并且使您的架构复杂化以避免您实际上没有遇到的性能瓶颈是一种经典的反模式。
  • 谢谢,我已经使用列表和 O(n),这是正确的做法。

标签: redis


【解决方案1】:

如何在有序集合上执行 BRPOPLPUSH 的原子等价物?

对不起,你不能。我们实际上在添加 ZPOP 家族时讨论过这个问题并决定反对它:“但是我不赞成 BZPOPZADD 部分,因为相反,列表的经验表明这通常不是一个好主意,不幸的是,添加消息处理可能会使用其他方式。BZPOPZADD 和 BRPOPLPUSH 等最糟糕的是级联效应,它们在复制中造成很多问题,我们的 BRPOPLPUSH 复制在某些方面仍然不正确(我们可以谈论如果你愿意的话)。” (参考:https://github.com/antirez/redis/pull/4879#issuecomment-389116241

我非常怀疑将屏蔽 BZRPOPMIN 也放入 MULTI,我这样做对吗?

当然,无论如何都不能在事务中调用阻塞命令。

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    相关资源
    最近更新 更多