3 ZooKeeper序列化和网络通信协议详解
序列化机制 zookeeper. jute 包 0:23:00 0:33:00
4个类 (Record InputArchive OutputArchive Index)
持久化机制 zookeeper.server.persistence 包 0:33:00 ~ 0:46:00
zookeeper本身是一个 leader, follower 对等架构(内部选举 leader)
每个节点上都保存了整个系统的所有数据
每个节点上的都把数据放在磁盘一份,放在内存一份
5个类 ( Txnlog SnapShot FileSnap FileTxnlog FileTxnSnaplog )
网络通信框架和 监听机制 apache.zookeeper.server 包 0:46:00 ~ 0:57 :00
2个类 (ClientCnxn ServerCnxn)
image监听机制 (Watcher Watcher Manager WatchedEvent(KeeperState EventType ) )
imageWatcher,接口类型,其定义了process方法,需子类实现。
Event,接口类型,Watcher的内部类,无任何方法。
KeeperState,枚举类型,Event的内部类,表示Zookeeper所处的状态。
EventType,枚举类型,Event的内部类,表示Zookeeper中发生的事件类型。
WatchedEvent,表示对ZooKeeper上发生变化后的反馈,包含了KeeperState和EventType。
ClientWatchManager,接口类型,表示客户端的Watcher管理者,其定义了materialized方法,需子类实现。
ZKWatchManager,Zookeeper的内部类,继承ClientWatchManager。
MyWatcher,ZooKeeperMain的内部类,继承Watcher。
ServerCnxn,接口类型,继承Watcher,表示客户端与服务端的一个连接。
WatchManager,管理Watcher。
4 源码分析
4.1 服务启动 0:59 :00 ~ 2:50:00
入口:\apache\zookeeper\server\quorum\QuorumPeerMain
main 方法——》
QuorumPeer类的 start()
4大步骤:
4.1.1 装载数据 0:59 :00 ~ 1:57:00
/**
* 刚启动的时候,需要加载数据库, 从磁盘中的 数据快照文件 和 comitted logs 中恢复
* 涉及到的核心类是 ZKDatabase,并借助于 FileTxnSnapLog 工具类将 snap 和 transaction log
* 反序列化到内存中,最终构建出内存数据结构 DataTree。
* 总结:从事务日志目录dataLogDir和数据快照目录dataDir中恢复出DataTree数据
* 涉及到的核心类是ZKDatabase,并借助于FileTxnSnapLog工具类将snap和transaction log反序列化到内存中,最终构建出内存数据结构DataTree
*/
loadDataBase();
返回最大事务 zxid
4.1.2 准备通信连接 1:57:00 ~ 2:07:00
/**
* 服务连接:开启对客户端的连接端口,启动ServerCnxnFactory主线程
* ServerCnxnFactory的作用:构建reactor模型的EventLoop,Selector每隔1秒执行一次select方法来处理IO请求,
* 并分发到对应的代表该客户端的ServerCnxn中并利用doIO进行处理
* NIOServerCnxnFactory 负责 创建 ServerCnxn 负责和客户端进行数据读写通信的
* 调用这句代码的时候,跳转到 new ZooKeeperThread(this).start()
* this = cnxnFactory
* 跳转到自己的 run 方法
*/
cnxnFactory.start(); // 卡住了
4.1.3 选举 2:07:00 ~ 2:24:00
利用最大事务 zxid
/**
- 开始选举, 这儿并不是真正的选举,而是只是初始化选举需要的各种组件
*/
startLeaderElection();
/**
- TODO_MA 到此为止,一定要记得:
- 1、FastLeaderElection 的 WorkerReceiver 和 WorkerSender 都启动好了。
- 2、QuorumCnxManager 的 Listen监听 也启动好了,等待有其他 Server 的链接的话,就会创建成对的 RecvWorker 和 SendWorker
/
/* - 线程启动 跳转到 run() 方法。
- 记得,上面的代码执行完了之后,会跳转到 run() 方法。 因为 QuorumPeer 是一个线程!
- 启动QuorumPeer线程,在该线程中进行服务器状态的检查
*/
super.start();
#### 4.5 启动过程图
![image.png](https://img.haomeiwen.com/i11332520/92696c2b1a54d718.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
#### 选举机制
网友评论