Zookeeper
概念
zk是开源的具有高可用、高性能、具有分布式的数据一致性,为分布式应用提供服务的数据管理及协调apache项目。
工作机制
客户端是观察者订阅特定被观察者节点状态的程序
特点
- 如果更新数据的时候有一个节点挂了其他的依然能更新
- 等节点复活后会同步数据
- 所有的请求都由Leader处理
- 由于更新时顺序进行的,所谓实时性是在请求被处理才能读到最新数据
核心功能
- 数据发布订阅
- 负载均衡
- 命名服务
- 分布式协调/通信
- 集群管理
- Master选举
- 分布式锁
- 分布式队列
数据发布和订阅(配置中心)![image-20210419111707943](https://i-blog.csdnimg.cn/blog_migrate/52174e8f0d20ff4990cedfe2742235f0.png)
- 发布/订阅一般有两种设计模式:推模式和拉模式,服务端主动将数据更新发送给所有订阅的客户端称为推模式;客户端主动请求获取最新数据称为拉模式,Zookeeper采用了推拉相结合的模式,客户端向服务端注册自己需要关注的节点,一旦该节点数据发生变更,那么服务端就会向相应的客户端推送Watcher事件通知,客户端接收到此通知后,主动到服务端获取最新的数据。
- 若将配置信息存放到Zookeeper上进行集中管理,在通常情况下,应用在启动时会主动到Zookeeper服务端上进行一次配置信息的获取,同时,在指定节点上注册一个Watcher监听,这样在配置信息发生变更,服务端都会实时通知所有订阅的客户端,从而达到实时获取最新配置的目的。
- 程序总是需要配置的,如果程序分散部署在多台机器上,要逐个改变配置就变得困难。好吧,现在把这些配置全部放到zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好。
负载均衡
- 分布式系统为了保证可用性,通常通过副本的方式来对数据和服务进行部署,而对于客户端吧来说,只需要在这样对等的服务提供方式中选择一个来执行相关的业务逻辑,以达到优化资源使用、最大化吞吐率、最小化响应时间和避免过载的目的。怎么选,这就是负载均衡的应用。
- zk实现负载均衡就是通过watcher机制和临时节点判断哪些节点宕机来获得可用的节点实现的:
命名服务
集群管理![image-20210419112715025](https://i-blog.csdnimg.cn/blog_migrate/ad4815678db148e60107660f1b0785e5.png)
-
所谓集群管理无在乎两点:是否有机器退出和加入、选举master。
对于第一点,所有机器约定在父目录GroupMemgers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它上船了。新机器加入 也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了。
对于第二点,我们稍微改变一下,所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。
分布式锁
- 有了zookeeper的一致性文件系统,锁的问题变得容易。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
- 对于第一类,我们将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。厕所有言:来也冲冲,去也冲冲,用完删除掉自己创建的distribute_lock 节点就释放出锁。
- 对于第二类, /distribute_lock 已经预先存在,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。
stat结构体
(1)
czxid
-创建节点的事务zxid每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。
事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么zxid1在zxid2之前发生。
2)
ctime
- znode被创建的毫秒数(从1970年开始(3)
mzxid
- znode最后更新的事务zxid(4)
mtime
- znode最后修改的毫秒数(从1970年开始)(5)
pZxid
-znode最后更新的子节点zxid(6)
cversion
- znode子节点变化号,znode子节点修改次数(7)
dataversion
- znode数据变化号(8)
aclVersion
- znode访问控制列表的变化号(9)
ephemeralOwner
- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。(10)
dataLength
- znode的数据长度(11)
numChildren
- znode子节点数量
监听器原理
- socket通信
- 创建两个线程,一个
listener
,一个connect
- 通过connect线程将注册监听事件发送给zookeeper集群的监听列表中。
- 被监听对象发生变化,则将事件发送给
listener
的peocess
中
选举机制
- 半数以上节点存活则集群存活
- 按启动顺序开始投票
- 先给自己投票
- 交换投票信息
- 先比较
zxid
若相同再比较myid
,小的把自己的票投给大的