How to create a distributed lock with Redis?

前端 未结 5 1217
广开言路
广开言路 2020-12-28 17:37

On the redis documentation, I found a primitive lock can be implemented via SETNX:

http://redis.io/commands/setnx

  • C4 sends SETNX lo

相关标签:
5条回答
  • 2020-12-28 18:18

    Using redis >= 2.6 the LUA script solution would be great. Lua script always executed atomically so:

    --lockscript, parameters: lock_key, lock_timeout
    local lock = redis.call('get', KEYS[1])
    if not lock then    
        return redis.call('setex', KEYS[1], ARGV[1], "locked");
    end
    return false
    

    The another solution based on new options of SET command

    SET lock_key "locked" EX lock_timeout NX 
    

    Using redis < 2.6 the pattern with multi can be used:

    MULTI
    SETNX tmp_unique_lock some_value
    EXPIRE tmp_unique_lock
    RENAMENX tmp_unique_lock real_lock
    EXEC
    
    0 讨论(0)
  • 2020-12-28 18:23

    follow the link
    nice project explaining locking
    http://redis.io/topics/distlock
    https://github.com/mrniko/redisson

    0 讨论(0)
  • 2020-12-28 18:28

    Use SET instead of SETNX. SET accepts arguments for expiration time in seconds and milliseconds instead of UNIX timestamp value.

    The old SETNX based pattern is documented only for historical reasons.

    From SETNX description:

    NOTE: Starting with Redis 2.6.12 it is possible to create a much simpler locking primitive using the SET command to acquire the lock, and a simple Lua script to release the lock. The pattern is documented in the SET command page.

    0 讨论(0)
  • 2020-12-28 18:42

    The new arguments for SET are enough for setting the lock, but these only work on Redis >= v2.6.12 you also need to think about how the lock will be unset and expire etc.

    I've written a post on our Engineering blog about distributed locks using Redis. It covers scripting on how to set and release the lock reliably, with validation and deadlock prevention. I also include a module written in Node.js you can use for locking straight out of the box.

    0 讨论(0)
  • 2020-12-28 18:44

    I gem'ed out the SET EX NX solution that misterion mentioned to a cool gem - simple_redis_lock

    The code is simple and looks like this:

    def lock(key, timeout)
      if @redis.set(key, Time.now, nx: true, px: timeout)
        begin
          yield
        ensure
          release key
        end
      end
    end
    
    0 讨论(0)
提交回复
热议问题