什么是zookeeer--抄自小灰

定位:zookeeper是一个分布式协调服务,可以在分布式系统中共享配置,协调锁资源,提供命名服务

1、zookeeper的数据模型:(类似数据结构中的树、文件系统的目录)
在这里插入图片描述
树是由节点组成,zookeeper的数据存储也是基于节点,这种节点称为Znode,znode的引用方式就是路径引用。如下所示:
在这里插入图片描述
2、znode中都包含了什么?
在这里插入图片描述
data:znode存储的数据信息
acl:记录znode的访问权限,即哪些人或哪些IP可以访问本节点
stat:包含znode的各种元数据,比如事务ID、版本号、时间戳、大小等等
child:当前节点的子节点引用,类似于二叉树的左孩子和右孩子
需要注意的是,zookeeper是为读多写少的场景所设计,znode并不是用来保存大规模业务数据的,每个节点的数据最大不能超过1MB.

3、zookeeper的基本操作和事件通知
创建节点:create
删除节点:delete
判断节点是否存在:exists
获得一个节点的数据:getData
设置一个节点的数据:setData
获取节点下的所有子节点:getChildren

其中读操作的时候,zookeeper客户端在请求读操作的时候,可以选择是否设置watch。
什么是watch?
相当于znode上的触发器,当znode发生改变,就会触发znode上注册的对应事件,请求watch的客户端会接收到异步通知。
如下所示:
1、客户端调用getData方法,watch参数是true,服务端收到请求,返回节点数据,并且在对应的哈希表里插入被watch的znode路径,以及watcher列表:
在这里插入图片描述
2、当被watch的znode已删除,服务端会查找哈希表,找到该znode对应的所有watcher,异步通知客户端。并且删除哈希表中对应的key-value。(应该是客户端连接zk的时候,引入的sdk包中维持了一个长连接?也可能是短连接吧。)
在这里插入图片描述

4、zookeeper的一致性
为了防止zk单机挂掉的情况,zk维护了一个集群。
在这里插入图片描述
zk service集群是一主多从结构,在更新数据时,首先更新到主节点,然后再同步到从节点。而读取数据时,直接读取任意从节点。

如何保证从节点的数据一致性?zk采用了ZAB协议。ZAB(zookeeper atomic broadcast )

5、ZAB协议
zab协议中定义了三种节点状态。(这里的节点,应该是指的每台zk)
Looking:选举状态
Following:Follower节点(从节点)所处于的状态
Leading:Leader节点(主节点)所处状态。

最大ZXID:节点本地的最新事务编号,包含epoch和计数两部分。epoch是纪元的意思,相当于raft算法选主时候的term。
假如zk当前的主节点挂掉了,集群会进行崩溃恢复。zab的崩溃恢复分为三个阶段:

a、leader election
选举阶段,此时集群中的节点处于looking状态,会各自向其他节点发起投票,投票当中包含自己的服务器ID和最新事务ID(ZXID)
.在这里插入图片描述
接下来,节点会用自身的ZXID和从其他节点接收到的ZXID比较,如果发现别人的ZXID比自己的大,也就是数据比自己新,那么就重新发起投票,投票给目前已知最大ZXID所属节点。
在这里插入图片描述
每次投票后,服务器都会统计投票数量,判断是否有某个节点得到半数以上的投票。如果存在这样的节点,该节点将会成为准leader,状态变为leading。其他节点的状态变为following。

2、Discovery
发现阶段。用于在从节点中发现最新的zxid和事务日志。(虽然leader被选为了主节点,已经是集群里数据最新的了,但是为了防止某些意外情况,比如因网络原因在上一阶段产生多个leader的情况)
leader需要接收所有follower发来各自的最新epoch值。leader从中选出最大的epoch,基于此值加1,生成新的epoch分发给各个follower。各个follower收到全新的epoch 后,返回ack给leader,带上各自最大的zxid和历史事务日志。leader选出最大的zxid,并更新自身历史日志。

3、synchronization
同步阶段,把leader刚才收集得到的最新历史事务日志,同步给集群中所有的follower,只有当半数follower同步成功,这个准leader才能成为正式的leader。

5、zab如何实现写入数据的?
上面说到了zk是通过zab协议,实现故障恢复的。那么zk又是如何实现主从数据的写入的呢?
写入数据,涉及到zab协议的broadcast阶段。
简单来说,就是zk常规情况下更新数据的时候,由leader广播到所有的follower,过程如下:
a、客户端发出写入数据请求给任意follower
b、follower把写入数据请求转发给leader
c、leader采用二阶段提交方式,先发送propose广播给follower
d、follower接到propose消息,写入日志成功后,返回ack消息给leader
e、leader接到半数以上ack消息,返回成功给客户端,并且广播commit请求给follower
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章