深入浅出Zookeeper---2、应用场景-灵析社区

提笔写架构

ZK的应用场景

服务注册发现



 分布式服务架构中,服务的注册与发现是最核心的基础服务之一,注册中心可以看做是分布式服务架构的通信中心。

 Zookeeper集群,通过监听机制,实现服务信息的订阅:


 Zookeeper是采用ZAB协议保证了数据的强一致性。ZAB协议的实现原理是怎样?ZK是如何实现选举, Paxos算法又是如何运用的?这个在后面算法章节会讲到。

分布式锁

分布式锁的实现需要注意的:

 同步访问共享资源。

  • 锁的可重入性:递归调用不会被阻塞、不会发生死锁(synchronized methodA(), ReentrantLock)
  • 锁的超时:避免死锁、死循环等意外情况
  • 锁的阻塞:保证原子性等 ->下单(范围广, 包含商品, 账户资金, 下单信息生成,将粒度细化。)
  • 锁的特性支持:阻塞锁、可重入锁、公平锁、联锁、信号量、读写锁

分布式锁的使用需要注意:

  • 分布式锁的开销, 能不能用就不用
  • 加锁的粒度
  • 加锁的方式(并发量大, 缓存做实现)

基于ZK的分布式锁实现:

 整体思想:每个客户端发起加锁时,生成一个唯一的临时有序节点。 如何判断锁是否创建呢?只需要判断是否存 在临时节点(若存在, 则根据序号判断)。

ZK的分布式锁的优缺点:

 优点: 可以有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。 缺点: 性能上不如基于缓存实现的分布式锁。ZK的强一致性, 一个事务的操作在所有节点都同步完成。

ZK是如何实现分布式锁?

排它锁

定义: 如果某个事务(Transaction)对数据对象(Object)加上了排他锁,那么在整个加锁期间,只允许该事务对数据进行读取或更新操作,其他任何事务不能对该数据对象做任何操作,直到该事务释放了排他锁…

 排它锁实现流程:

 Zookeeper 的强一致性特性,能够很好地保证在分布式高并发情况下节点的创建一定能够保证全局唯一性, 即Zookeeper将会保证客户端无法重复创建一个已经存在的数据节点。可以利用Zookeeper这个特性,实现排他锁。


 实现步骤:

  1. 定义锁:通过Zookeeper上的数据节点来表示一个锁

2.获取锁:客户端通过调用 create方法创建锁的临时节点,创建成功的客户端代表获取锁,没有获得锁 的客户端在该节点上注册Watcher监听,以便实时获取lock节点的变更情况

3.释放锁

  符合以下两种情况都可以让锁释放
 

  • 当前获得锁的客户端发生宕机或异常,那么Zookeeper上这个临时节点就会被删除
  • 正常执行完业务逻辑,客户端主动删除自己创建的临时节点

共享锁

定义: 如果事务Transaction对数据对象Object加上了共享锁,在不是写操作事务下, 其他事务仍可以对Object进行读取操作。

 共享锁实现流程:

  1. 定义锁

2.获取锁

  如果是读请求,则创建 /lockpath/[hostname]-R-序号 节点,如果是写请求则创建 /lockpath/[hostname]-W- 序号节点

3.读写顺序判断处理

  • 创建完节点后,获取 /lockpath 节点下的所有子节点,并对下面所有注册的子节点变更进行 Watcher监听;
  • 确定自己的节点序号在所有子节点中的顺序, 针对顺序的大小, 处理读写请求流程;
  • 对于读请求:1. 如果没有比自己序号更小的子节点,或者比自己序号小的子节点都是读请求,那么表明可以成功获取到了共享锁;2. 如果有比自己序号小的子节点有写请求,那么先进行等待 。
  • 对于写请求,如果存在比自己更小的节点,那么进行等待;
  • 接收到Watcher通知后, 再次处理上面的读写请求流程
  • 4.释放锁
      与排它锁逻辑一致。
      基于ZK的共享锁实现流程:


共享锁产生的羊群效应解决方案

羊群效应是什么?

 羊群是一种很散乱的组织,平时在一起也是盲目地左冲右撞,但一旦有一只头羊动起来,其他的羊也会不假思索地一哄而上,全然不顾前面可能有狼或者不远处有更好的草。因此,“羊群效应”就是比喻人都有一种从众心理,从众心理很容易导致盲从,而盲从往往会陷入骗局或遭到失败。
羊群效应该如何解决呢?

 其实只需要改进Watch的监听处理流程:

利用ZK实现公平选举

ZK是如何实现集群选举呢?

  1. 基于ZK的Watch机制,ZK的所有节点的读取操作,都可以附带一个Watch,一旦数据有变化,Watch 就会被触发,通知客户端数据发生变动。
  2. 基于ZK实现的分布式锁,这里的锁是指排它锁,任意时刻,最多只有一个进程可以获取锁。

什么是公平选举?

  公平选举是要遵循公平性,大家都遵循规则,依照请求先后顺序,参与选举。
选举处理流程


  三台节点向ZK集群创建Sequence类型节点,每个节点所创建的序号不一样, 他们会判断自己所创建的节点 序号是否为最小,这个与顺序有关, 如果是最小, 则选取为Leader,否则为Follower角色。
如果Leader出现问题如何处理?

  Leader 所在进程如果意外宕机,其与 ZooKeeper 间的 Session 结束,由于其创建的节点为Ephemeral类 型,故该节点会自动被删除。
Follower角色节点是如何感知的?

  在公平模式下, 每个Follower都会 Watch 序号刚好比自己序号小的节点。在上图中,调用方节点2会Watch 节点/Master/Leader1,调用方节点3会Watch节点/Master/Leader2。如果Leader宕机,/Master/Leader1 删除,调用方节点2就能得到通知。节点2先判断自己的序号 2 是不是当前最小的序号,在该场景下,其序号 为最小,所以节点2成为新的Leader。

利用ZK实现非公平选举

什么是非公平选举?

 非公平选举就是没有遵循选举的公平性,仍然沿用上面的例子: 村子里要选举村长,领导通知大家在明早7点前排队在前十的人就可以参与选举,这个时候有人晚到,但借关系插队排在前面,这个就是非公平选举。
选举处理流程


 三台调用节点向ZK集群创建Non-sequence节点,但只会有一个调用节点创建成功,谁能够抢占资源在ZK集 群创建成功,与顺序无关,则竞选为Leader,其他客户端则创建失败,成为Follower角色。

阅读量:2027

点赞量:0

收藏量:0