使用 SETNX 的单实例 Redis 锁

bla*_*een 10 locking go redis

我需要从应用程序客户端连接到单个 Redis 实例。

由于客户端将在 Kubernetes 中复制,我正在研究有关锁的 Redis 文档,以防止客户端副本之间的竞争。

在谷歌搜索和阅读之后,我将注意力集中在这两个资源上:

有趣的是,SETNX文档明确建议不要使用SETNX来实现锁,指出它基本上已经过时了:

为了支持 Redlock 算法,不鼓励使用以下模式 [...]

我们仍然记录旧模式,因为某些现有实现链接到此页面作为参考。

然而 Redlock 算法是专门为分布式锁量身定制的,因此当一个人试图锁定多个 Redis 实例时 - 它们实际上是指多个master

更进一步,库redsync (golang) 声明New函数如下:

func New(pools []Pool) *Redsync {
    return &Redsync{
        pools: pools,
    }
}
Run Code Online (Sandbox Code Playgroud)

它看起来毫无疑问是为支持 Redis 集群上的锁定而设计的。

在我的用例中,我将只连接到一个 Redis 实例。

也许我可以只使用 redsync 包并传递一个长度为 1 的切片,但在我看来,该SETNX模式在单个 Redis 实例上也能正常工作。

我是否正确地看到了这一点?谢谢

Kev*_*nry 7

是的,确实 Redlock 算法是为分布式 Redis 系统设计的,如果您使用的是单个实例,那么使用SETSETNX文档中描述的更简单的锁定方法应该没问题

但是,更重要的一点是:您可能不需要使用锁来避免多个 Redis 客户端之间的冲突。Redis 锁通常用于保护一些外部分布式资源(有关此问题的更多信息,请参阅我的回答here)。在 Redis 本身中,通常不需要锁;由于 Redis 的单线程特性,很多命令已经是原子的,你可以使用事务或 Lua 脚本来组合任意复杂的原子操作。

所以我的建议是设计您的客户端代码以使用原子性来避免冲突,而不是尝试使用锁(分布式或其他方式)。