分布式锁:ZooKeeper与Redis的区别
发布网友
发布时间:2023-04-10 01:53
我来回答
共1个回答
热心网友
时间:2023-09-13 06:39
在分布式系统中,分布式锁的应用场景是非常广泛的。Redis和ZooKeeper是目前比较常见的实现方案,那它们之间有什么区别呢,我们应该如何选择?
对于ZooKeeper来说,它的会话与服务端是通过心跳保持连接的,当心跳超时客户端会收到链接丢失的事件,通常来说这不是问题,因为ZK的客户端对自动连接。但如果一直连接不上,服务端会在会话有效期之后,将会话置为过期。这里有个很重要的细节,即使会话已经过期了,在重新连接上服务器之前,客户端永远也不知道自己已经过期了,因为ZooKeeper的会话过期是由服务器端触发并通知客户端的。
这样,如果客户端a与ZooKeeper服务器之间的通信长时间断开的话,客户端a会误以为自己并没有过期,只是临时性的链接丢失,但实际上服务端有可能已经将它置为过期,而这时其它与ZooKeeper服务器通信正常的客户端就有可能获取同一个锁(因为服务端在将客户端a置过期的同时会清除它所创建的临时节点),进而造成两个客户端同时访问临界区的资源。
要解决这个问题也不难,在链接丢失和重新建立链接时,客户端都会收到相应的事件通知。我们可以在客户端维护一个状态变量(比如valid),在链接丢失时将它置为false,并在重新建立链接后将它置为true,并在客户端访问临界区的资源代码中不定期的检查valid的值,一旦发生valid值变为false时,就说明链接丢失了,这时就暂停临界区资源的访问,并等待重新建立链接。
这么做挺麻烦的,大大增加了使用锁的复杂性。但是否真需要这么玩也是看具体的场景的:
使用Redis实现的锁,并不存在这样的问题,因为key并不会因为客户端怎么样而被删除。但它也有麻烦的一面,为了防止客户端长时间阻塞或者故障宕机而导至锁无法释放,我们需要在加锁的时候指定一个过期时间,不过成本确实比ZooKeeper的实现要低很多。
经过以上分析,我们不难得出以下结论:分布式锁的实现使用ZooKeeper还是redis来实现,取决于加锁的目的。