Concurrency Redis BITSET和WATCH
我正在使用Redis创建一个算法,用于从一个范围中声明未使用的整数。我的解决方案是基于我对这个问题的回答 这个解决方案使用BITPOS和BITSET,为了避免竞争条件,我还使用了WATCH/MULTI/EXEC。为了测试并发性方面,我创建了一个bash脚本,该脚本同时尝试10次并行查找空闲数,以研究EXEC命令的可能结果 我发现EXEC从未返回null,即使监视的密钥被另一个客户端修改。我添加了延迟,以便有足够的时间引发并发修改,从而触发监视机制,从而导致EXEC失败,但事实并非如此 所以基本上我有一段代码:Concurrency Redis BITSET和WATCH,concurrency,redis,watch,bitset,Concurrency,Redis,Watch,Bitset,我正在使用Redis创建一个算法,用于从一个范围中声明未使用的整数。我的解决方案是基于我对这个问题的回答 这个解决方案使用BITPOS和BITSET,为了避免竞争条件,我还使用了WATCH/MULTI/EXEC。为了测试并发性方面,我创建了一个bash脚本,该脚本同时尝试10次并行查找空闲数,以研究EXEC命令的可能结果 我发现EXEC从未返回null,即使监视的密钥被另一个客户端修改。我添加了延迟,以便有足够的时间引发并发修改,从而触发监视机制,从而导致EXEC失败,但事实并非如此 所以基本上
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
}
还有一个循环,在10个不同的进程中调用SETBIT mykey,N,1表示N=1..10
我发现EXEC从未返回null,即使在被监视的一段时间内另一个进程确实修改了密钥
问题:
基于位的Redis命令是否不支持WATCH?
如果它被支持,为什么在这些情况下它没有被触发?我是否测试/挑起了错误?据我所知,如果在监视的时间段内另一个客户端/连接修改了密钥,那么WATCH应该使EXEC失败,并且从10个不同的Linux进程调用它,每个进程创建自己的连接,似乎符合这一要求?
在这种特殊情况下,WATCH和MULTI实际上提供了什么吗?BITSET返回该位的前一个值,因此原子性不应该仅仅通过以下伪代码算法来保证:
没有任何文档表明WATCH不支持位设置命令
我觉得你的代码很好,所以很难说为什么它不工作。为了进一步研究它,您必须提供一个而不是伪代码。然而
没错,这里不需要事务,这个算法应该保证原子性
while (true) {
number = BITPOS mykey, 0
if (number > maxNumber) THROW ERROR
wasUsed = SETBIT mykey, number, 1
if (!wasUsed) {
return number
}
}