作者回复: 分布式锁这么设计的原因是为了避免羊群效应,公平性是一个副作用。这样设计是有你说的那个问题。
作者回复: > 老师,这个znode是不是就是类似redis中的一个key的概念呢 你可以把znode理解成Redis的一个key。但是znode之间有层次关系。 > 另外我们这边经常用redis来做分布式锁(setnx命令),只是redis没有将请求者进行排队,感觉redis要简单一些,能否点评一下这两种锁的使用场景及优缺点。 1. 如果一个调用setnx的Redis客户端crash,它设置的key还会存在,换言之锁不会自动释放。在ZooKeeper里面,我们用临时节点表示锁,如果ZooKeeper客户端crash,它的锁会自动释放。 2. ZooKeeper实现的锁可以在锁释放时只通知一个锁请求者,还保证锁分配的FIFO。 个人感觉ZooKeeper的锁方案更加完备。setnx只是一个简单的SET if Not eXists命令,如果你的场景很简单也可以用它。 另外Redis(https://redis.io/commands/setnx)本身也不推荐使用setnx了。 > The following pattern is discouraged in favor of the Redlock algorithm which is only a bit more complex to implement, but offers better guarantees and is fault tolerant.
作者回复: 分布式锁性能保证的关键点是避免herd effect。本节的实现是保证锁释放的时候,只有一个锁请求者收到通知。
作者回复: 您的场景可以创建持久性节点。
作者回复: 是的,ZooKeeper本身不提供锁,但是可以使用znode操作来实现。但是实现出来的锁也是advisory的,这就是说用户可以忽视这个锁直接获取资源。 Chubby的锁机制也是advisory的。
作者回复: 一个目录下的顺序性节点是统一进行编号的,用的是int类型。如果一个目录下面有超过2^32个顺序性节点的话,会有您说的问题。但是这种情况实际发生的概率很小,所以ZooKeeper没有针对这种情况做处理。
作者回复: zookeeper的源代码。https://github.com/apache/zookeeper/tree/branch-3.5.5/zookeeper-recipes/zookeeper-recipes-lock