如果 2 个工人同时在一个有序集合的同一个元素上调用 ZREM 会发生什么?它是否会向实际删除元素的工作人员返回 true 而向另一个返回 false 以指示它不存在,或者它是否会对两者都返回 true?换句话说,ZREM 在内部是原子的吗?
问问题
2763 次
1 回答
5
Redis(大部分)是单线程的,所以它的所有操作都是原子的,ZREM 也不例外。但是,您的问题实际上是关于以原子方式执行“ZPOP”,因此有两种可能的方法可以做到这一点。
选项 1:WATCH/MULTI/EXEC
在伪代码中,这是一个乐观事务的样子:
:start
WATCH somekey
member = ZREVRANGE somekey 0 0
MULTI
ZREM somekey member
if not EXEC goto :start // or quit trying
选项 2:Lua 脚本
zpop.lua:
local member = redis.call('ZREVRANGE', KEYS[1], 0, 0)
return redis.call('ZREM', KEYS[1], member)
redis-cli --eval zpop.lua somekey
注意 - 原子性的重要性 如果您决定不使用这些确保原子性的机制,您将比您想象的更快遇到问题。这是一个可能的情况:
Process A Redis Server Process B
ZREVRANGE ------------>
<------------- foo
<--------- ZADD +inf bar
OK --------->
ZREM foo -------------->
<-------------- 1
在上面的示例中,在 A 获取 foo 之后,B 插入了一个得分高得离谱的 bar,因此它成为集合中的顶部元素。但是,A 将继续并删除先前位于顶部的 foo。
于 2015-07-29T08:35:36.443 回答