windardyang
V2EX  ›  Redis

关于 Python redis 的 Lock 有两个疑问

  •  1
     
  •   windardyang · Aug 24, 2018 · 7307 views
    This topic created in 2992 days ago, the information mentioned may be changed or developed.
    set name token nx ex timeout
    

    python 中的 redis Lock 实际上就是以上函数来实现锁。但是原生的 Lock 是先 setnx 在 expire,LuaLock 是使用 lua 脚本先 setnx 在 expire,所以有两个问题。

    1. 为什么将两个步骤合二为一呢?是因为 setnx key value 比 set key value nx 高级一些么?
    2. 使用要使用 lua 脚本,就比原生执行高级一些么?

    函数在 redis/lock.py

    原生的 Lock

        def do_acquire(self, token):
            if self.redis.setnx(self.name, token):
                if self.timeout:
                    # convert to milliseconds
                    timeout = int(self.timeout * 1000)
                    self.redis.pexpire(self.name, timeout)
                return True
            return False
    

    使用 LuaLock

        # KEYS[1] - lock name
        # ARGV[1] - token
        # ARGV[2] - timeout in milliseconds
        # return 1 if lock was acquired, otherwise 0
        LUA_ACQUIRE_SCRIPT = """
            if redis.call('setnx', KEYS[1], ARGV[1]) == 1 then
                if ARGV[2] ~= '' then
                    redis.call('pexpire', KEYS[1], ARGV[2])
                end
                return 1
            end
            return 0
        """
    
    5 replies  •  2018-08-25 09:36:35 +08:00
    seven2016
    seven2016
    Aug 24, 2018
    1
    刚好在学习 redis

    - set key value nx 是分布式锁的奥义所在,两个步骤合成一个原子操作不会有并发问题
    - Redis 服务器内部可以直接执行 Lua 代码,恩,有这样一句话,学好 redis,必会 Lua。(逃
    scriptB0y
    scriptB0y
    Aug 24, 2018
    2
    你所说的 “原生的 lock ” “ python 中的 redis lock ” “ lualock ” 分别指什么? 为什么“原生的 lock ”是一段 Python 代码?
    windardyang
    windardyang
    OP
    Aug 24, 2018
    3
    @scriptB0y #2 指的是 `redis/lock.py` 代码里的两个 Lock 类,只截取了获得锁的部分代码,完整的类请看源代码。
    windardyang
    windardyang
    OP
    Aug 24, 2018
    4
    @seven2016 #1 我的意思也是 `set key value nx` 较现有方式好一些,可是现在它并不是这样实现。
    helloSpringBoot
    helloSpringBoot
    Aug 25, 2018 via Android
    5
    `set name token nx ex timeout ` 是客户端用的,跟服务端实现不一样很正常。
    假设客户端实现也是先加锁,在设置超时:加完锁,客户端挂掉了怎么办? 这样锁不就释放不了了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   4976 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 07:23 · PVG 15:23 · LAX 23:23 · JFK 02:23
    ♥ Do have faith in what you're doing.