如何理解Redis RedLock的潜在失败场景与Zookeeper的锁一致性保障?

redis有红锁机制
zookeeper有ZAB协议。
两者都是必须超过一半的节点响应成功才算成功
那为什么基于redlock还是有可能会加锁失败?而zookeeper则认为可以保证一定能一致呢?
比如网上常举例的,redis有A B C D E五个节点,现在A B C 写入了一个锁,然后C还没来得及持久化就重启,或者C突然不可用被踢出,又新加了一个节点F。客户端2在D E F上加了同一把锁成功。

那zookeeper就没有上述问题吗?
再者,它加锁加的是一个临时有序节点,那如果这个节点自己崩溃了呢?客户端认为获取到了这把锁,然后这个节点自己崩溃了,那客户端2是不是就可以加锁了?

阅读 1.1k
avatarAI BotBETA

Redis RedLock 的潜在失败场景

Redis RedLock 的设计目标是在分布式系统中提供一种相对可靠的锁机制,但它并不保证绝对的一致性,这主要源于 Redis 的几个特性:

  1. 网络分区和节点故障:在 Redis RedLock 的实现中,如果客户端成功地在多个 Redis 节点上设置了锁,但随后一些节点(如示例中的 C)在锁信息被持久化之前失败或重启,这可能导致锁的状态不一致。新的节点(如 F)加入后,如果它不了解之前锁的状态,就可能允许新的客户端(如客户端 2)获取到锁,尽管该锁可能仍被其他客户端持有。
  2. 时钟偏移:Redis RedLock 依赖于时间戳来判断锁是否过期,如果系统间存在时钟偏移,可能导致锁提前释放或延迟释放。
  3. 持久化问题:Redis 支持多种持久化策略(如 RDB 快照和 AOF 日志),但这些策略并不保证每次写操作都立即持久化到磁盘,因此节点故障可能导致最近的数据丢失。

Zookeeper 的锁一致性保障

相比之下,Zookeeper 通过其 ZAB(ZooKeeper Atomic Broadcast)协议提供了更强的一致性保障:

  1. 全局顺序:ZAB 协议保证了所有写操作的全局顺序性,这意味着在 Zookeeper 中创建或删除节点的操作会按照全局顺序执行,从而避免了锁状态的不一致。
  2. 持久性:Zookeeper 的数据存储在磁盘上,并且每个写操作都会同步到磁盘,确保了数据的持久性。即使 Zookeeper 节点崩溃,重启后也能从磁盘恢复最新的数据状态。
  3. 临时有序节点:在 Zookeeper 中,锁通常通过创建临时有序节点来实现。这些节点在客户端会话结束时会自动删除。如果客户端崩溃,其会话将超时,Zookeeper 会自动删除该客户端创建的临时节点,从而释放锁。此时,其他客户端可以安全地获取锁。

Zookeeper 的崩溃恢复

对于 Zookeeper 节点崩溃的情况,由于它使用了临时有序节点,并且这些节点与客户端会话绑定,因此当客户端崩溃时,其会话会超时,导致临时节点被删除。这确保了即使客户端崩溃,锁也能被正确释放,其他客户端可以安全地获取锁。

综上所述,Redis RedLock 因其基于内存和可能存在的持久化延迟,存在锁状态不一致的风险,而 Zookeeper 通过其强一致性的设计和数据持久化机制,提供了更高的锁一致性保障。

1 个回答

Martin 和 antirez 两位大佬就 RedLock 是否安全在很多年前展开过一次讨论,那次讨论很有名,网上也有大把的解读。

非要说一个结论的话就是:所有带超时机制的分布式锁,都无法在某个节点取得锁之后完美解决 NPC 问题。因此 Zookeeper 同样也不是百分百安全的。

P.S. NPC 即 Network Delay, Process Pause, Clock Drift 三个分布式问题的首字母缩写。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏