Redis BRPOP和ZADD原子

时间:2018-04-20 09:23:57

标签: ruby lua redis atomicity

我需要BRPOP然后将弹出的值添加到带有ZADD的有序集合中。我看到两个解决方案(我正在使用Ruby):

  1. 编写执行这两个操作的Lua脚本。但是,Lua脚本无法阻止,因为它们会同时压住整个服务器。所以这个解决方案不起作用;
  2. 使用redis-rb' multi { ... }阻止。但是,在这里我不能使用ZADD命令中的弹出值,因为这不是redis-rb实现此块的方式。
  3. 通过这些,我只能用非原子方式来实现这一点,即使用redis-rb来顺序触发这些命令。但是,我真的需要原子性。实现这个目标的方法是什么?

3 个答案:

答案 0 :(得分:3)

您可以将RPOPZADD包装在Lua脚本中,例如RPOPZADD,以原子方式运行它们,并在客户端做一些工作来模拟阻塞行为。

以下是伪代码:

while (true) {
    bool ret = redis.eval(RPOPZADD);    // return immediately
    if (!ret) {
        // No item in the list, wait for a while
        sleep(1);
    }
}

答案 1 :(得分:3)

TL; DR是不可能的。

你可以,如果你没有挂在列表上的poppin',请查看我的新模块以及对Redis核心的闪亮的新请求。

  1. 泽POP模块:https://github.com/itamarhaber/zpop
  2. 拉请求#4879“实现[B] Z [REV] POP和相应的单元测试”:https://github.com/antirez/redis/pull/4879

答案 2 :(得分:2)

您没有指定需要排序集的原因,如果您可以解决它并使用列表,则可以使用BRPOPLPUSH将元素原子地移动到其他列表,并在以后对其进行排序非原子方式。

另一种选择是编写一个Redis模块,为您做到这一点 - modules blocking ops