当前位置:   article > 正文

Zookeeper(二)——ZK实现分布式锁(读写锁、羊群效应、curator实现)、zk的watch机制(客户端和 curator )、ZK 集群搭建、ZAB协议(选举和崩溃恢复、主从数据同步)

zk实现分布式锁

Zookeeper(二)——ZK实现分布式锁(读写锁、羊群效应、curator实现)、zk的watch机制(客户端和 curator )、ZK 集群搭建、ZAB协议(选举和崩溃恢复、主从数据同步)

一、ZK实现分布式锁

1、zk中锁的种类

  • 读锁(读锁共享-共享锁):大家都可以读。上锁前提:之前的锁没有写锁
  • 写锁(写锁排他-排他锁):只有得到写锁的才能写。上锁前提:之前没有任何锁

2、zk如何上读锁

  • 创建一个临时序号节点,节点的数据是read,表示是读锁
  • 获取当前zk中序号比自己小的所有节点
  • 判断前面的节点中是否有写锁
    • 获取读锁时会创建一个临时节点并查看前面的节点是否有写锁
    • 如果满足上述条件,则上锁成功。

在这里插入图片描述

3、zk如何上写锁

  • 创建一个临时序号节点,节点的数据是write,表示写锁
  • 获取zk中所有的子节点
  • 判断自己是否是最小的节点:
    • 如果是,则上写锁成功
    • 如果不是,说明前面还有锁,则上锁失败,监听最小节点,如果最小节点有变化,则再执行第二步。

在这里插入图片描述
之所以要判断自己是否是最小节点,因为如果是最小节点,则立马可以上锁。

4、羊群效应

如果用上述的上锁方式,只要有节点发生变化,就会触发其他节点的监听事件,这样对zk的压力非常大。

如果有100个并发,都要上写锁,但是目前已经有一个锁存在,则这100个并发都会去监听第一个锁,如果第一个锁发生变化,则这100个节点只有一个能成功,接着剩下99个又去监听这一个节点,这样会对 zk 的压力非常大。

而羊群效应,可以调整成链式监听。解决这个问题:
在这里插入图片描述

每个节点都只要监听上一个节点即可。

如果三节点断开了,则四节点会去监听2节点。

5、curator 实现读写锁

a、获取读锁

在这里插入图片描述

b、获取写锁

在这里插入图片描述

二、zk 的 watch 机制

1、Watch 机制介绍

我们可以把Watch理解成是注册在特定Znode上的触发器当这个Znode发生改变,也就是调用了create,delete,setData方法的时候,将会触发Znode上注册的对应事件,请求Watch的客户端会收到异步通知。

具体交互过程如下:

  • 客户端调用getData方法,watch参数是true。服务端接到请求,返回节点数据,并且在对应的哈希表里插入被Watch的Znode路径,以及Watcher列表。
    在这里插入图片描述
    当被Watch的Znode已删除,服务端会查找哈希表,找到该Znode对应的所有Watcher,异步通知客户端,并且删除哈希表中对应的key-value。
    在这里插入图片描述

客户端使用了 NIO 通信模式监听服务端的调用

a、get -w /xxx —— 一次性监听某个节点

在这里插入图片描述

监听 test9 节点,当9节点发生变化,比如:
在这里插入图片描述

那么监听的变化信息:
在这里插入图片描述

可以看到,这里只会告诉我们发生了变化,但是发生了什么变化还是需要自己去操作相关命令去查看。

如果是删除节点,那么告诉我们的信息会发生变化:
在这里插入图片描述

如果是创建子节点,监听并不会被触发。

2、zkCli客户端使用Watch

create /test date
get -w /test	  一次性监听节点。
ls -w /test		  监听目录(只监听目录)。创建和删除子节点会收到通知,但是子节点中新增节点不会被监听到。
ls -R -w /test	  监听子节点中节点的变化,但内容的变化不会收到通知。
  • 1
  • 2
  • 3
  • 4

3、Curator客户端使用Watch

在这里插入图片描述

当服务端节点数据发生变化时:
在这里插入图片描述

三、ZK 集群

1、ZK 集群角色

zookeeper集群中的节点有三种角色

  • Leader:处理集群的所有事务请求,集群中只有一个Leader
  • Follwoer:只能处理读请求,参与Leader选举
  • Observer:只能处理读请求,提升集群读的性能,但不能参与Leader选举

在这里插入图片描述

2、集群搭建

先把开启的单节点服务停止。

先进到该目录下:
/root/apache-zookeeper-3.7.1-bin/zkdata

在这里插入图片描述

然后创建四个文件夹:
在这里插入图片描述

然后每个 zk 的文件夹都需要创建一个文件,叫 myid,然后给一个值,这个值是描述该节点(是服务器节点)的唯一标识,这个值不能重复。

然后重新进入 conf 目录,准备四个 zoo.cfg 配置文件去启动四台 zk:
在这里插入图片描述

在这里插入图片描述

然后修改 zoo1.cfg 配置文件:
在这里插入图片描述

在这里插入图片描述
上面的 abserver 打错了,是 observer。

保存后再复制三份,zoo2 zoo3 zoo4 。

然后修改这些复制出来的配置文件,只需要修改日志路径,还有对客户端的端口号即可:
在这里插入图片描述

3、4同理。

接着启动这四个文件:
在这里插入图片描述

可以通过下面命令查看是什么状态的机子:
在这里插入图片描述

四、ZAB协议

1、什么是ZAB协议

zookeeper作为非常重要的分布式协调组件,需要进行集群部署,集群中会以一主多从的形式进行部署。zookeeper为了保证数据的一致性,使用了ZAB(Zookeeper Atomic Broadcast)协议,这个协议解决了Zookeeper的崩溃恢复和主从数据同步的问题。
在这里插入图片描述

2、ZAB协议定义的四种节点状态

  • Looking:选举状态
  • Following:Following节点(从节点)所处的状态
  • Leading:Leader节点(主节点)所处状态
  • Observing:观察者节点所处的状态

3、集群上线Leader选举过程

在这里插入图片描述

4、崩溃恢复时的Leader选举

Leader建立完后,Leader周期性地不断向Follower发送心跳(ping命令,没有内容的socket)。当Leader崩溃后,Follower发现socket通道已关闭,于是Follower开始进入到Looking状态,重新回到上一节中的Leader选举过程,此时集群不能对外提供服务。

5、主从服务器之间的数据同步

在这里插入图片描述
看第六步,可以看到是半数以上的 ack,这个半数是对候选还是整个集群?

这个半数是针对整个集群,可以很明显看到候选中数量是偶数,如果是半数以上,只有奇数才好判断半数以上。

6、Zookeeper中的NIO与BIO的应用

  • NIO
    • 用于被客户端连接的2181端口,使用的是NIO模式与客户端建立连接
    • 客户端开启Watch时,也使用NIO,等待Zookeeper服务器的回调
  • BIO
    • 集群在选举时,多个节点之间的投票通信端口,使用BIO进行通信

7、Zookeeper追求的一致性

Zookeeper在数据同步时,追求的并不是强一致性,而是顺序一致性(事务id的单调递增)

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号