二、zookeeper内部原理
2.1 节点类型
分为持久性和短暂性节点。
1) 持久性:客户端与服务器断开连接以后,创建的节点不删除;
-- 分为带序号的持久性节点和不带序号的持久性节点。
2) 短暂性:客户端与服务器断开连接以后,创建的节点删除;
-- 分为带序号的短暂性节点和不带序号的短暂性节点。
-- 如何理解带序号的呢?
1) 在zk分布系统中,顺序号用于为所有事物进行全局排序,这样客户端根据顺序号推测事件的顺序。
2) 顺序号是指当前节点下的节点数量,不可重复使用。如之前已经创建了一个节点,但是现在将其进行删除,再创建一个节点,顺序号是往后进行累加。
-- 说明
1) 短暂节点下不能创建子节点;
2) 一个节点包含该节点的具体存储的内容和子节点的元数据信息。
2.2 Stat结构体
1)czxid-创建节点的事务zxid
每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。
事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么zxid1在zxid2之前发生。
2)ctime 被创建的毫秒数(从1970年开始)
3)mzxid 最后更新的事务zxid
4)mtime 最后修改的毫秒数(从1970年开始)
5)pZxid-znode最后更新的子节点zxid
6)cversion 子节点变化号,znode子节点修改次数
7)dataversion 数据变化号
8)aclVersion 访问控制列表的变化号
9)ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。
10)dataLength 数据长度
11)numChildren 子节点数量
2.3 监听器原理(重点)
监听原理详解:
1) 首先有一个main()线程;
2) 在main线程中创建zookeeper客户端,这时就会有两个线程,一个负责网络通信(connet),一个负责监听(listener);
3) 通过connect线程将注册的监听事件发送给zookeeper;
4) 在zookeeper的注册监听器列表中将注册的监听事件添加到列表中;
5) zookeeper监听到有数据或者是路径发生变化时,就会将这个消息发送到listener线程;
6) listener线程内部调用process方法();
2.4 选举机制(重点)
总结:选举机制由节点启动的顺序、myid、数据的zxid、服务器的数量有关。
大致顺序为:
1)zxid大的当选(99%情况下都是相等的);
2)根据节点启动的顺序,比较myid,在未到达半数的服务器数量以前,所有节点的票都将投给myid大的服务器,一旦到达了半数以上的服务器被启动(此时可以对外提供服务)时,myid最大的节点当选leader,其余的服务器为follower。
2.5 写数据流程
1) Client 向zookeeper申请写数据,发送一个写请求;
2) 如果这个服务器不是leader,则该服务器将接收到的请求转发给leader;
3) leader将这个写的请求广播给所有的follower服务器,所有的服务器将写的事件写入队列中,并向leader发送准备就绪的成功消息;
4) 当leader收到了半数以上的服务器返回了成功的消息以后,则说明该写的操作可以执行,则leader向所有的follower发送提交消息,所有的服务器收到信息以后则执行队列中的写操作;
5) 对应的服务器完成写操作以后会通知client,数据写入成功。