set name token nx ex timeout
python 中的 redis Lock 实际上就是以上函数来实现锁。但是原生的 Lock 是先 setnx 在 expire,LuaLock 是使用 lua 脚本先 setnx 在 expire,所以有两个问题。
- 为什么将两个步骤合二为一呢?是因为
setnx key value比set key value nx高级一些么? - 使用要使用 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
"""