V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
windardyang
V2EX  ›  Redis

关于 Python redis 的 Lock 有两个疑问

  •  1
     
  •   windardyang · Aug 24, 2018 · 6826 views
    This topic created in 2808 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 valueset 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
        1
    seven2016  
       Aug 24, 2018
    刚好在学习 redis

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