Zookeeper分布式锁实现Curator十一问(五)

pivoteic
发布于 2022-6-15 17:06
浏览
0收藏

 

八、如何实现公平锁

 

其实使用临时顺序节点实现的分布式锁就是公平锁。所谓的公平锁就是加锁的顺序跟成功加锁的顺序是一样的。

 

因为节点的顺序就是被唤醒的顺序,所以也就是加锁的顺序,所以天生就是公平锁。

 

九、如何实现读写锁

 

读写锁使用如下。

Zookeeper分布式锁实现Curator十一问(五)-鸿蒙开发者社区

创建节点的时候,节点的内容中会有一个标记来代表当前节点加的是什么类型的锁。

Zookeeper分布式锁实现Curator十一问(五)-鸿蒙开发者社区

当需要加写锁时,需要判断自己创建的节点是否排在第一位,如果是就能加锁成功,所以一旦前面有节点,不论前面加是读锁还是写锁,那么都是加锁失败,实现了读写互斥和写写互斥。当然写锁和读锁都是可以重入加锁的。

 

当需要加读锁的时候,会去判断自己创建节点的前面有没有写锁,如果没写锁,那么说明前面加的都是读锁,那么读锁就能加锁成功,读读不互斥,如果前面有写锁,那么就加锁失败(自己加的写锁除外),读写互斥。

 

十、如何实现批量加锁

 

批量加锁的意思就是同时加几个锁,只有这些锁都算加成功了,才是真正的加锁成功。

 

Redisson也实现了批量加锁的功能,Redisson的实现通过RedissonMultiLock类实现的,RedissonMultiLock会去遍历需要加的锁,然后每个都加成功之后才算加锁成功。Curator是封装了InterProcessMultiLock类来实现的批量加锁的,那么InterProcessMultiLock如何实现的呢?

 

使用代码如下。

Zookeeper分布式锁实现Curator十一问(五)-鸿蒙开发者社区

InterProcessMultiLock的acquire的方法实现。

Zookeeper分布式锁实现Curator十一问(五)-鸿蒙开发者社区

从这里可以看出,InterProcessMultiLock也是遍历传入的锁,然后每个锁都加锁成功了,InterProcessMultiLock才算加锁成功。

 

所以从这里可以看出,跟Redisson实现的批量加锁的实现思想上基本是一样的,都是遍历加锁。

 

十一、ZK分布式锁和Redis分布式锁到底该选谁

 

这是一个比较常见的面试题。

 

redis分布式锁:

 

  • 优点:性能高,能保证AP,保证其高可用,
  • 缺点:正如Redisson的那篇文章所言,主要是如果出现主节点宕机,从节点还未来得及同步主节点的加锁信息,可能会导致重复加锁。虽然Redis官网提供了RedLock算法来解决这个问题,Redisson也实现了,但是RedLock算法其实本身是有一定的争议的,有大佬质疑该算法的可靠性;同时因为需要的机器过多,也会浪费资源,所以RedLock也不推荐使用。

 

zk分布式锁:

 

  • 优点:zk本身其实就是CP的,能够保证加锁数据的一致性。每个节点的创建都会同时写入leader和follwer节点,半数以上写入成功才返回,如果leader节点挂了之后选举的流程会优先选举zxid(事务Id)最大的节点,就是选数据最全的,又因为半数写入的机制这样就不会导致丢数据
  • 缺点:性能没有redis高

 

所以通过上面的对比可以看出,redis分布式锁和zk分布式锁的侧重点是不同的,这是redis和zk本身的定位决定的,redis分布式锁侧重高性能,zk分布式锁侧重高可靠性。所以一般项目中redis分布式锁和zk分布式锁的选择,是基于业务来决定的。如果你的业务需要保证加锁的可靠性,不能出错,那么zk分布式锁就比较符合你的要求;如果你的业务对于加锁的可靠性没有那么高的要求,那么redis分布式锁是个不错的选择。

 

最后,希望通过这两篇文章,让大家对于zookeeper分布式锁和redis分布式锁的实现有个更好的认识。

 

文章转自公众号:三友的java日记

标签
已于2022-6-15 17:06:49修改
收藏
回复
举报
回复
    相关推荐