Redis BITSET和WATCH
我正在使用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
}
也是一个循环调用SETBIT mykey, N, 1
的N = 1..10
,在10个不同的进程。
我发现EXEC
,即使在监视的时间内肯定由另一个进程修改了密钥,也永远不会返回null。
问题:
- 是否
WATCH
完全不支持基于BIT的Redis命令? - 如果得到支持,为什么在这种情况下不触发它?我是否在错误地测试/挑衅?据我了解,如果密钥已在监视的时间内 被另一个客户端/连接 修改,并且从10个不同的Linux进程(每个进程都创建自己的连接)中调用此密钥似乎符合该要求,
WATCH
应该EXEC
失败吗? __ - 在这种特殊情况下,也
WATCH
与MULTI
实际提供的东西吗?BITSET
返回该位的先前值,因此不应仅通过以下伪代码算法来保证原子性:while (true) {
number = BITPOS mykey, 0
if (number > maxNumber) THROW ERROR
wasUsed = SETBIT mykey, number, 1
if (!wasUsed) {
return number
}
}
回答:
没有文档表明
WATCH
不支持位设置命令。您的代码对我来说看起来很正确,因此很难说出为什么它不起作用。为了进一步研究它,您必须提供MCVE而不是伪代码。然而…
是的,这里不需要事务,此算法应保证原子性。
以上是 Redis BITSET和WATCH 的全部内容, 来源链接: utcz.com/qa/427358.html