Redis BITSET和WATCH [英] Redis BITSET and WATCH

查看:129
本文介绍了Redis BITSET和WATCH的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Redis创建一种算法来声明某个范围内未使用的整数。我的解决方案基于我对这个 SO问题。

I'm using Redis to create an algorithm for claiming unused integers from a range. My solution is based on the answer I got for this SO question.

此解决方案使用 BITPOS BITSET ,为了避免出现比赛情况,我还使用了 WATCH / MULTI / EXEC 。为了测试并发性,我创建了一个bash脚本,该脚本同时尝试并行查找10个空闲数字,以调查 EXEC 命令的可能结果。

This solution uses BITPOS and BITSET, and to avoid race conditions, I also use WATCH/MULTI/EXEC. In order to test the concurrency aspects I created a bash script that concurrently attempts to find a free number 10 times in parallel, to investigate the possible outcomes of the EXEC command.

我发现,即使监视的密钥被另一个客户端修改, EXEC 也从未返回null。我添加了一些延迟,以便有足够的时间来激发应该触发监视机制的并发修改,以使 EXEC 失败,但是并没有。

What I found was that EXEC never returned null, even when the watched key was modified by another client. I added delays such that there was plenty of time to provoke a concurrent modification that should trigger the watch mechanism so that EXEC fails, but it didn't.

所以基本上我有这段代码:

So basically I had this piece of code:

while (true) {
  WATCH mykey
  number = BITPOS mykey, 0
  if (number > maxNumber) THROW ERROR

  (deliberate delay)

  MULTI
  SETBIT mykey, number, 1
  if EXEC != null return number
}

,还有一个循环,调用 SETBIT mykey,N,1 ,其中 N = 1..10 , 10个不同的进程。

and also a loop that calls SETBIT mykey, N, 1 for N = 1..10, in 10 different processes.

我发现 EXEC 永远不会返回null,即使密钥确实由

What I found was that EXEC never returned null, even when the key was definitely modified by another process during the watched period of time.

问题:


  1. WATCH 根本不支持基于BIT的Redis命令吗?

  2. 如果支持,为什么不这样做?在这种情况下被操纵?我是否在错误地测试/挑衅?据我了解,如果密钥已被另一个客户端/连接修改,则 WATCH 应该会使 EXEC 失败。 在这段时间内,并从10个不同的Linux进程(每个进程都创建自己的连接)中调用它似乎符合该要求?

  3. 在这种情况下, WATCH MULTI 实际上提供了什么吗? BITSET 返回该位的先前值,因此不应仅通过以下伪代码算法来保证原子性:

  1. Is WATCH simply not supported for BIT based Redis commands?
  2. If it is supported, why wasn't it triggered under these circumstances? Am I testing/provoking it incorrectly? As I understand it, WATCH should make EXEC fail if the key has been modified by another client/connection during the watched period of time, and calling this from 10 different Linux processes, each creating its own connection, seems to fit that requirement?
  3. In this particular case, does WATCH and MULTI actually offer anything? BITSET returns the previous value of that bit, so shouldn't atomicity be guaranteed simply by the following pseudo-code algorithm:



    while (true) {
      number = BITPOS mykey, 0
      if (number > maxNumber) THROW ERROR

      wasUsed = SETBIT mykey, number, 1

      if (!wasUsed) {
        return number
      }
    }


推荐答案


  1. 没有文档表明 WATCH 不支持位设置命令。

您的代码对我来说很合适,因此很难说出为什么它不起作用。要对其进行进一步调查,您必须提供 MCVE 而不是伪代码。但是...

Your code looks right to me, so it's hard to say why it isn't working. To investigate it further you'd have to provide a MCVE rather than pseudocode. However...

是的,这里不需要事务,此算法应保证原子性。

You're right, you don't need a transaction here, this algorithm should guarantee atomicity.

这篇关于Redis BITSET和WATCH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆