V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
windardyang
V2EX  ›  Redis

关于 Python redis 的 Lock 有两个疑问

  •  1
     
  •   windardyang · 2018-08-24 19:15:48 +08:00 · 6060 次点击
    这是一个创建于 2286 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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 条回复    2018-08-25 09:36:35 +08:00
    seven2016
        1
    seven2016  
       2018-08-24 20:50:47 +08:00
    刚好在学习 redis

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