使用 Redis 的分布式锁中的竞争条件
Race condition in distributed locks with Redis
我在 http://redis.io/topics/distlock 上阅读了关于使用 Redis 的分布式锁的 post。有一个 lua 脚本来描述如何做 "unlock"。
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
我认为这个模型存在竞争条件:
- 客户端 A 获取了 3 秒到期的锁。
SET key randomstring1 NX PX 3000
- 睡眠 2.99 秒。
- 客户端A释放锁,调用上述代码
- 条件成立。
if redis.call("get",KEYS[1]) == ARGV[1] then
- 原始密钥过期
- 客户端B获得了作者锁。
SET key randomstring2 NX PX 3000
- 客户端A删除密钥。
- 客户端B的锁被客户端A删除了!
不,这里没有竞争条件。 LUA 脚本以原子方式执行。这意味着在 LUA 脚本完成它们工作之前,不会处理来自其他连接(客户端)的任何命令(即使是实际处理过期项目的 Redis 内部 cron)。
我在 http://redis.io/topics/distlock 上阅读了关于使用 Redis 的分布式锁的 post。有一个 lua 脚本来描述如何做 "unlock"。
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
我认为这个模型存在竞争条件:
- 客户端 A 获取了 3 秒到期的锁。
SET key randomstring1 NX PX 3000
- 睡眠 2.99 秒。
- 客户端A释放锁,调用上述代码
- 条件成立。
if redis.call("get",KEYS[1]) == ARGV[1] then
- 原始密钥过期
- 客户端B获得了作者锁。
SET key randomstring2 NX PX 3000
- 客户端A删除密钥。
- 客户端B的锁被客户端A删除了!
不,这里没有竞争条件。 LUA 脚本以原子方式执行。这意味着在 LUA 脚本完成它们工作之前,不会处理来自其他连接(客户端)的任何命令(即使是实际处理过期项目的 Redis 内部 cron)。