Zookeeper内部原理

Zookeeper内部原理

1、节点类型

每一个znode都有不同的生命周期,而生命周期长短取决于znode的节点类型。Zookeeper提供了4中节点类型。

zookeeper节点

节点类型 解释
持久节点(Persistent) 默认节点类型,当前会话关闭后,该节点仍然存在;只有删除节点操作,该节点才会消失;持久化节点可创建子节点;
持久顺序节点(Persistent Sequential) 默认节点类型,当前会话关闭后,该节点仍存在;只有进行删除节点操作,该节点才会消失;该类型节点名后缀为自增数字;持该类型节点可创建子节点。
临时节点(Epheneral) 当前会话关闭后,该节点会被删除;该类型节点不能创建子节点。
临时顺序节点(Epheneral Sequental) 当前会话关闭后,该节点会被删除;该类型节点名后缀为自增数字;该类型节点不能创建子节点。

2、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最后修改的毫秒数

(5)pZxid:znode最后最后更新的子节点zxid

(6)cversion:znode子节点变化号,znode子节点修改次数

(7)dataversion:znode数据变化号

(8)aclVersion:znode访问控制列表的变化号

(9)ephenmeralOwner:如果是临时节点,这个是znode拥有者的session id,如果是持久节点,session id就是0

(10) dataLength:znode的数据长度

3、监听器原理

一、步骤

​ (1)首先要有一个main()线程

(2)在main线程中创建Zookeeper客户端,这时就会创建两个线程,一个负责网络连接通信(connet),一个负责监听(listener) 。

(3)通过connect线程将注册的监听事件发送给Zookeeper。

(4)在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中。

(5)Zookeeper监听到有数据或路径变化,就会将这个消息发送给listener线程。

(6) listener线程内部调用了process()方法。

二、常见的监听

(1)监听节点数据的变化

get path [ watch]

(2)监听子节点增减的变化

ls path [watch]

监听原理

实例说明

一、节点的值变化监听

(1)在 node1 主机上注册监听/client1节点数据变化

[zk: localhost:2181(CONNECTED) 26] get -w /client1

(2)在node2主机上修改/client1节点的数据

[zk: localhost:2181(CONNECTED) 1] set /client1 "xisi"

(3)观察 node1主机收到数据变化的监听

WATCHER:
WatchedEvent state:SyncConnected
type:NodeDataChanged
path:/client1

注意:在node2再多次修改/client1的值,node上不会再收到监听。因为注册一次,只能监听一次。想再次监听,需要再次注册。

二、节点的子节点变化监听(路径变化)

(1)在 node1主机上注册监听/client1节点的子节点变化

[zk: localhost:2181(CONNECTED) 1] ls -w /client1

[yg, tt]

(2)在 node2 主机/client2 节点上创建子节点

[zk: localhost:2181(CONNECTED) 2] create /client1/shizi "shizi"

Created /client1/shizi

(3)观察 node1 主机收到子节点变化的监听

WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged
path:/client1

4、选举机制类型

一、zk的选举机制中的概念

SID:服务器ID。用来唯一标识一台ZooKeeper集群中的机器,每台机器不能重复,和myid一致。
ZXID:事务ID。ZXID是一个事务ID,用来标识一次服务器状态的变更。在某一时刻,集群中的每台机器的ZXID值不一定完全一致,这和 ZooKeeper服务器对于客户端“更新请求”的处理逻辑有关。
Epoch:每个Leader任期的代号。没有Leader时同一轮投票过程中的逻辑时钟值是相同的。每投完一次票这个数据就会增加。
LOOKING:选举中,正在寻找Leader
FOLLOWING:随从状态,同步leader状态,参与投票
Leader:领导者,差不多是master,在zookeeper中只有leader才有写的权限,following只有读的权限
OBSERVING:观察者状态,不同leader状态,不参与投票

二、核心选举原则

  • Zookeeper集群中只有超过半数以上的服务器启动,集群才能正常工作;
  • 在集群正常工作之前,myid小的服务器给myid大的服务器投票,直到集群正常工作,选出Leader;
  • 选出Leader之后,之前的服务器状态由Looking改变为Following,以后的服务器都是Follower。
  • 如果集群没有Leader(非全新选举),Epoch大的服务器当选leader;
  • 如果Epoch相等,比较ZXID(事物ID),事物ID大的,当选leader;
  • 如果Epoch相等,ZXID相等,则比较myId(服务器id),服务器id大的当选Leader,服务器id是不重复;

三、选举机制类型

(1)全新集群选举(第一次启动)

假设目前有三台服务器,分别是1号、2号、3号;

zxid都设置为0,myid决定谁是Leader。
首先1号启动,启动一次选举,1号投给自己一票,由于其他服务器没有启动,无法收到1号的投票信息,此时1号处于Looking(竞选状态);
2号启动,启动选举,2号给自己投一票,并且与1号交换信息,此时1号发现2号的myId比自己投票服务器(服务器1)的myId大,此时1号0票,2号2票,2>(3/2),服务器2的票数最多,超过半数,那么2号当选leader,1号更改状态为following,2号更改状态为leading;
3号启动,启动选举,给自己投一票,此时与之前启动的1号、2号交换信息,此时1号、2号并没有处于Looking(竞选中)状态,不会更改选举状态,3号一票,服从多数,此时3号更改状态为following;

注意:当集群服务器有5台时,前面的服务器1和服务器2,都是LOOKING,服务器1票数为0,服务器2票数为2,当启动第三台服务器时,服务器3的myid大,服务器2会把票数给服务器3,(服务器启动会给自己投一票)这时服务器3票数为3选为Leader,其他的都是follow,之后启动的服务器也是follow;

(2)非全新集群选举(非第一次启动)

zixd起到主导因素,决定谁是Leader

如果leader服务器挂了,那么整个集群将暂停对外服务,进入新一轮leader选举,其过程和启动时期的leader选举过程基本一致。Leader挂掉后,余下的服务器都将自己的服务器状态变更为looking,然后开始进入Leader选举过程。服务器1号、2号、3号,此时2号是Leader,如果2号停电挂掉之后,1号、3号无法连接到Leader,知道Leader挂了,他们就知道必须选出一个新的 Leader,于是纷纷将自己的状态都修改为 LOOKING 状态:
比如1号的ZXID(事物id)为:77,Epoch(任期代号)为:1,myid(服务器id):1;3号的ZXID(事物id)为:80,Epoch(任期代号)为:1,myid(服务器id):3;此时3号为leader。

如果follow挂掉了,此时集群还是可以对外提供服务,挂掉一个是达到整个集群总数的半数以上的,如果挂掉的follow恢复之后,还是以 Follower 的身份加入到集群中来,并且仍然以当前 Leader 的信息来同步,即使它的Epoch大于其他的服务器。

四、读写数据流程

读写过程

(1)Client向Zookeeper的server1发送一个写请求,客户端写数据到服务器1上;

(2)如果server1不是Leader,那么server1会把接收到的写请求转发给Leader;然后Leader会将写请求转发给每个server

​ server1和server2负责写数据,并且两个Follower的写入数据是一致的,保存相同的数据副本;

​ server1和server2写数据成功后,通知Leader

(3)当Leader收到集群半数以上的节点写成功的消息后,说明该写操作执行成功;

​ eg:这里是3台服务器,只要2台Follower服务器写成功就ok

​ 因为client访问的是server1,所以Leader会告知server1集群中数据写成功;

(4)被访问的server1进一步通知client数据写成功,这时,客户端就知道整个写操作成功了。

二、读数据流程
相比写数据流程,读数据流程就简单得多;因为每台server中数据一致性都一样,所以随便访问哪台server读数据就行;

没有写数据流程中请求转发、数据同步、成功通知这些步骤。

posted @ 2022-11-18 15:10  食尸之鬼  阅读(113)  评论(0)    收藏  举报