ZREM on Redis Sorted Set

时间:2015-07-29 08:33:10

标签: redis sortedset redis-py

如果2名工作人员同时在排序集的同一元素上调用ZREM,会发生什么?是否会将实际删除元素的worker返回true而对另一个返回false以指示它不存在或者它是否会返回true?换句话说就是ZREM原子内部?

1 个答案:

答案 0 :(得分:3)

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插入具有荒谬高分的条形,因此它成为集合中的顶部元素。然而,A将继续并删除之前的顶级foo。