Reputation: 967
What will happen if 2 workers call ZREM on the same element of a sorted set at the same time? Will it return true to the worker which actually removes the element and false to the other to indicate it doesn't exist or will it return true to both? In other words is ZREM atomic internally?
Upvotes: 1
Views: 3749
Reputation: 49942
Redis is (mostly) single-threaded so all its operations are atomic and ZREM is no exception. Your question, however, is actually about doing a "ZPOP" atomically so there are two possible ways to do that.
Option 1: WATCH/MULTI/EXEC
In pseudo code, this is how an optimistic transaction would look:
:start
WATCH somekey
member = ZREVRANGE somekey 0 0
MULTI
ZREM somekey member
if not EXEC goto :start // or quit trying
Option 2: Lua script
zpop.lua:
local member = redis.call('ZREVRANGE', KEYS[1], 0, 0)
return redis.call('ZREM', KEYS[1], member)
redis-cli --eval zpop.lua somekey
Note - The Importance of Atomicity In case you decide not to use these mechanisms that ensure atomicity, you'll be running into issues sooner than you think. Here's a possible scenario:
Process A Redis Server Process B
ZREVRANGE ------------>
<------------- foo
<--------- ZADD +inf bar
OK --------->
ZREM foo -------------->
<-------------- 1
In the above example, after A fetches foo, B inserts bar with an absurdly high score so it becomes the top element in the set. A, however, will continue and remove the previously-at-the-top foo.
Upvotes: 5