一尘不染

如何使用Redis创建分布式锁?

redis

在redis文档中,我发现可以通过SETNX实现基本锁:

http://redis.io/commands/setnx

  • C4发送SETNX lock.foo以获取锁

  • 崩溃的客户端C3仍然保留它,因此Redis将以0答复C4。

  • C4发送GET lock.foo以检查锁是否过期。如果不是,它将hibernate一段时间并从头开始重试。

  • 相反,如果由于lock.foo上的Unix时间早于当前Unix时间而使锁过期,则C4尝试执行:

GETSET lock.foo

  • 由于GETSET语义,C4可以检查存储在key上的旧值是否仍然是过期的时间戳。如果是,则已获取锁。

  • 如果另一个客户端(例如C5)比C4快,并通过GETSET操作获得了锁定,则C4
    GETSET操作将返回未过期的时间戳。C4将仅从第一步重新启动。请注意,即使C4在将来几秒钟设置了密钥,这也不是问题。

但是,正如某些用户所评论的那样,使用UNIX时间戳作为到期时间要求客户端和服务器的时间完全同步。有没有更好的选择来在Redis中创建全局/分布式锁?


阅读 265

收藏
2020-06-20

共1个答案

一尘不染

使用SET代替SETNXSET接受参数以秒和毫秒为单位的到期时间,而不是UNIX时间戳值。

仅基于历史原因记录了基于SETNX的旧模式。

根据SETNX 描述

注意:从Redis
2.6.12开始,可以使用SET命令来获取锁,并使用简单的Lua脚本来释放锁,从而创建更简单的锁定原语。该模式记录在SET命令页面中。

2020-06-20