Redis BITSET和WATCH [英] Redis BITSET and 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.
问题:
- 是
WATCH
根本不支持基于BIT的Redis命令吗? - 如果支持,为什么不这样做?在这种情况下被操纵?我是否在错误地测试/挑衅?据我了解,如果密钥已被另一个客户端/连接修改,则
WATCH
应该会使EXEC
失败。 在这段时间内,并从10个不同的Linux进程(每个进程都创建自己的连接)中调用它似乎符合该要求? - 在这种情况下,
WATCH
和MULTI
实际上提供了什么吗?BITSET
返回该位的先前值,因此不应仅通过以下伪代码算法来保证原子性:
- Is
WATCH
simply not supported for BIT based Redis commands? - If it is supported, why wasn't it triggered under these circumstances? Am I testing/provoking it incorrectly? As I understand it,
WATCH
should makeEXEC
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? - In this particular case, does
WATCH
andMULTI
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
}
}
推荐答案
-
没有文档表明
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屋!