Search code examples
redisdistributed-lock

Race condition in distributed locks with Redis


I've read the post about distributed locks with Redis at http://redis.io/topics/distlock. There's a lua script to describe how to do "unlock".

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

I think there is a race condition with this model:

  1. Client A acquires the lock with 3 seconds expiration. SET key randomstring1 NX PX 3000
  2. Sleep 2.99 seconds.
  3. Client A releases the lock and call the above code.
  4. The condition is true. if redis.call("get",KEYS[1]) == ARGV[1] then
  5. The origin key expires
  6. Client B acquires anthor lock. SET key randomstring2 NX PX 3000
  7. Client A delete the key.
  8. Client B's lock is deleted by Client A!

Solution

  • No, here is no race condition. LUA scripts executes in atomic way. This means that no any commands from other connections (clients) would be processed before LUA script finish they work (even Redis internal cron which actually process expired items).