Zookeeper入门
Posted sky~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zookeeper入门相关的知识,希望对你有一定的参考价值。
Zookeeper入门
概述
Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。
Zookeeper 从设计模式的角度来开:是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper就通知已经注册的观察者做出相应的反应
特点
- Zookeeper由一个领导者,多个跟随着组成的集群
- 集群中只要有半数以上的节点存活,Zookeeper就可以正常服务。因此适合安装基数台服务器
- 全局数据一致:每个Server保存一份相同的数据副本,Client无论连接到哪个Server数据都是一致的
- 更新请求顺序执行,来自同一个Client的更新请求按照发送的顺序依次执行
- 数据更新原子性,一次数据更新要么成功要么失败
- 实时性,在一定时间范围内,Client能读取到最新的数据
结构
Zookeeper的数据模型的结构和Unix文件系统很类似,整体上可以看作是一棵树,每个节点都是一个ZNode,每个ZNode默认存储1MB的数据(因此不适合存过大的数据),每个ZNode都可以通过其路径来唯一标识。
Zookeeper = 文件系统 + 通知机制
应用场景
-
一般要求一个集群中,所有节点的配置信息是一致的,对配置文件修改后,希望能够快速同步到各个节点上,比如 kafka集群
实现:
可将配置信息写入Zookeeper上的一个Znode,各个客户端服务器监听这个Znode,一旦Znode中的数据被修改,Zookeeper将通知各个客户端服务器 -
分布式环境中实时掌握每个节点的状态是必要的,可以根据节点实时状态做出调整,Zookeeper可以实现实时监控节点状态变化
实现:
可将节点信息写入Zookeeper上的一个ZNode,监听这个ZNode可以获取他的实时状态变化
选举机制
Zookeeper分为leader 和 follower 两种
假设有五台服务器,初始的选举方法:
- 服务器1先启动,发起第一次选举。服务器1会投自己一票,此时服务器1只有一票,没有达到半数以上,无法选举成功,服务器1的状态为Looking
- 服务器2启动,再次发起选举,服务器1和2先投自己一票,然后交换选票信息,此时服务器1发现服务器2的myid比自己目前投票的大,就将投票改为服务器2,此时服务器1没有票,服务器2两票,但是此时并没有服务器的票数超过半数,所以无法选举成功,服务器1,2状态都保持Looking
- 服务器3启动,发起一次选举。和上述过程相似,此时服务器3的myid最大会获得3票,因为已经过半所以服务器3为Leader,服务器1,2为follower。并改变服务器1,2的状态为Following, 服务器3的状态为Leading
- 服务器4启动,发起选举,因为服务器1,2,3的状态都不是Looking所以不会再更改选票信息,最后服务器3三票,服务器4,自己投了一票,服务器4将自己的票投给服务器3,并将状态改为Following
- 服务器5同服务器4一样
SID: 服务器的ID,唯一标识,Zookeeper集群中的机器,每台机器都不可以重复,和myid一致
ZXID: 事务ID,ZXID是一个事务ID,用来标识一次服务器状态的变更。在某一时刻,集群中的每台机器的ZXID的值不一定完全一致,这与Zookeeper对客户端更新请求的处理逻辑有关
Epoch: 每个Leader任期的代号,没有Leader时,同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加
Zookeeper选举Leader的情况:
- 服务器初始化启动
- 服务器运行期间无法和Leader保持连接
当机器进入选举流程时,当前集群可能会处于以下两种状态:
- 集群中是存在Leader的。这种情况下,机器去选举Leader,会被告知当前服务器的Leader信息,该机器只要和Leader建立连接即可
- 集群中不存在Leader。当有Leader故障时,集群会选择新的Leader,选取的规则为:(1):比较EPOCH,大的胜出
(2):ECOPH相同是,比较事务Id即ZXID,大的胜出
(3):事务ID相同时,比较服务器ID,大的胜出
节点信息
节点信息:
- 持久:客户端和服务器断开连接后,创建的节点不删除
- 短暂:客户端和服务器断开连接后,节点会自己删除
节点类型:
- 持久化目录节点: 客户端与Zookeeper断开连接后,节点依旧存在
- 持久化顺序编号目录节点:客户端与Zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
- 临时目录节点:客户端与Zookeeper断开连接后,节点被删除
- 临时顺序编号目录节点:客户端与Zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
监听原理
- 首先需要一个main线程
- 在main线程中创建Zookeeper的客户端,这时会创建两个线程,一个负责网络连接通信,一个负责监听
- 通过connect线程,将注册的监听事件发给zookeeper
- 在zookeeper的注册监听器列表中,将注册的监听事件添加到列表中
- zookeeper监听到有数据或路径变化后,将这个消息发生给listener线程
- listener线程内部调用了process方法
写数据原理
- 对Leader节点进行写操作时:客户端将写数据发给Leader,Leader将请求发送给一个Fllower,当Follower节点收到后,回复给Leader,Leader统计目前有多少Follower收到了,如果已经过半,就回复给客户端,剩余的Follower慢慢写入
- 对Follower节点进行写操作时:客户端将写数据发给Follower,Follower先把请求发给Leader,Leader向发送给他的Follower再次发送数据,来确保接受的数据是正确的,Follower收到后向Leader发送确认请求。之后再依次向各个别的Follower发送写数据,当有过半的节点确认后,Leader向第一次客户端写入的Follower发送确认请求,Follower再向客户端进行确认。
分布式锁
服务端接收到客户端的请求后:
- 在/locks节点下,创建一个临时顺序节点
- 判断自己是不是当前节点下最小的节点,如果是,则获取到锁。如果不是,则对前一个节点进行监听
- 获取到锁、处理完业务后。delete节点去释放锁,然后下面的节点将收到通知,重复第二步的操作
以上是关于Zookeeper入门的主要内容,如果未能解决你的问题,请参考以下文章