在 Redis 中实现分布式锁通常可以使用 Lua 脚本来确保原子性操作。以下是一个简单的 Lua 脚本示例,用于实现 Redis 的分布式锁:
分布式锁的 Lua 脚本
-- KEYS[1] = lock_key
-- ARGV[1] = lock_value (unique value for the lock)
-- ARGV[2] = expire_time (lock expiration time in milliseconds)
if redis.call("EXISTS", KEYS[1]) == 0 then
redis.call("SET", KEYS[1], ARGV[1], "PX", ARGV[2])
return 1 -- Lock acquired
else
local current_value = redis.call("GET", KEYS[1])
if current_value == ARGV[1] then
-- The same client is trying to acquire the lock again, extend the expiration
redis.call("PEXPIRE", KEYS[1], ARGV[2])
return 1 -- Lock acquired
else
return 0 -- Lock not acquired
end
end
解锁的 Lua 脚本
解锁时,确保只有持有锁的客户端才能释放它。以下是解锁的 Lua 脚本示例:
-- KEYS[1] = lock_key
-- ARGV[1] = lock_value (unique value for the lock)
local current_value = redis.call("GET", KEYS[1])
if current_value == ARGV[1] then
redis.call("DEL", KEYS[1]) -- Release the lock if it matches the unique value
return 1 -- Lock released successfully
else
return 0 -- Unable to release the lock, it was not held by this client or has expired
end
使用示例
假设你使用的是 redis-py 库(Python),你可以这样调用上述脚本:
import redis
r = redis.Redis()
lock_key = "my_lock"
lock_value = "unique_identifier" # A unique identifier for your request/instance.
expire_time = 10000 # Lock expiration time in milliseconds.
# Acquire the lock using Lua script.
acquire_lock_script = """
-- [Lua script from above]
"""
result = r.eval(acquire_lock_script, 1, lock_key, lock_value, expire_time)
if result == 1:
print("Lock acquired!")
else:
print("Failed to acquire lock.")
# Do some work...
# Release the lock using unlock script.
release_lock_script = """
-- [Unlock Lua script from above]
"""
release_result = r.eval(release_lock_script, 1, lock_key, lock_value)
if release_result == 1:
print("Lock released.")
else:
print("Failed to release the lock.")
注意事项
- 确保每个请求都有唯一标识符(如 UUID)以避免不同请求间的冲突。
- 锁的有效期要根据业务需求设置,以防止死锁情况。
- 可以通过增加一些重试机制来提高获得锁的成功率。
内容由零声教学AI助手提供,问题来源于学员提问




