目录
- 1、ZAB的核心思想
- 2、leader消息写入机制
- 3、zookeeper到底是强一致性还是最终一致性?
- 4、一台机器上最多能启动多少个ZooKeeper客户端
- 5、2888和3888端口通信
- 6、ZooKeeper提供给运维人员使用的命令说明
- 7、zookeeper原生api注册监听器和curator注册监听器的区别
- 8、zookeeper 2181服务端初始化代码入口
- 9、客户端SendThread发送请求给服务端代码入口
- 10、客户端定期发送Ping心跳到服务端代码入口
- 11、过半follower返回ack触发commit操作代码入口
- 12、commit将数据写入内存数据库代码入口
- 13、基于ZooKeeper的sync实现强一致等待
- 14、watch监听器的类型
- 15、watch监听器注册代码入口
- 16、客户端回调监听器代码入口
- 17、客户端感知到zk服务端宕机的处理代码入口
- 18、leader向follower发送请求代码入口
- 19、follower处理leader请求代码入口
zookeeper的依赖:
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.5</version>
</dependency>
1、ZAB的核心思想
1、崩溃恢复(leader选举)
2、数据同步
2、leader消息写入机制
leader 写入,采用 2PC 模式过半写机制,将事务请求以 Proposal 提议广播到所有 Follower 节点,当集群中有过半的Follower 服务器进行正确的 ACK 反馈,那么Leader就会再次向所有的 Follower 服务器发送commit 消息,将此次提案进行提交
3、zookeeper到底是强一致性还是最终一致性?
明显,ZAB协议机制,zk一定不是强一致性
那么有没有可能,此时有的follower已经commit了,但是有的follower还没有commit?绝对会的,所以有可能其实某个客户端连接到follower01,可以读取到刚commit的数据,但是有的客户端连接到follower02在这个时间还没法读取到
所以zk不是强一致的,不是说leader必须保证一条数据被全部follower都commit了才会让你读取到数据,而是过程中可能你会在不同的follower上读取到不一致的数据,但是最终一定会全部commit后一致,让你读到一致的数据的
zk官方给自己的定义:顺序一致性
4、一台机器上最多能启动多少个ZooKeeper客户端
一台机器上,我们可以创建多少个zk客户端?也就是说可以跟zk servers建立多少个连接呢?是有限制的,默认来说60,3.4.0以前是10个
5、2888和3888端口通信
server.1=zk01:2888:3888
一般来说每台机器的3888端口,是用来在集群恢复模式的时候进行leader选举投票的,也就是说所有的机器之间进行选举投票的时候就是基于3888端口来的
2888的端口,是用来进行leader和follower之间进行数据同步和运行时通信的
6、ZooKeeper提供给运维人员使用的命令说明
命令格式:echo conf | nc localhost 2181
conf(查看配置)、cons(查看连接)、crst(重置客户端统计)、dump(输出会话)、envi(查看环境)、ruok(检查是否在运行)、stat(查看运行时状态)、srst(重置服务器统计)、wchs(查看watcher信息)、wchc(输出watche详细信息)、wchp(输出watcher,以znode为单位分组)、mntr(输出比stat更详细的)
7、zookeeper原生api注册监听器和curator注册监听器的区别
如果我们用原生的zk去注册监听器的话,监听子节点或者节点自己,如果发生了对应的事件,会通知你一次,但是下一次再有事件就不会通知了。zk原生的API里,需要你每次收到事件通知之后,都需要自己重新注册watcher
PathCache,NodeCache,给你的节点加监听器,如果说监听到了事件之后,然后得到了通知,下次他会自动给你重新注册监听器
8、zookeeper 2181服务端初始化代码入口
1、org.apache.zookeeper.server.NIOServerCnxnFactory#configure
2、org.apache.zookeeper.server.NIOServerCnxnFactory#run
9、客户端SendThread发送请求给服务端代码入口
org.apache.zookeeper.ClientCnxnSocketNIO#doTransport
10、客户端定期发送Ping心跳到服务端代码入口
org.apache.zookeeper.ClientCnxn.SendThread#run
====================================》
sendPing();
====================================》
org.apache.zookeeper.ClientCnxn.SendThread#sendPing
====================================》
org.apache.zookeeper.ClientCnxnSocketNIO#doTransport
11、过半follower返回ack触发commit操作代码入口
org.apache.zookeeper.server.quorum.Leader#processAck
====================================》
self.getQuorumVerifier().containsQuorum(p.ackSet)
====================================》
org.apache.zookeeper.server.quorum.flexible.QuorumHierarchical#containsQuorum
12、commit将数据写入内存数据库代码入口
org.apache.zookeeper.server.FinalRequestProcessor#processRequest
====================================》
rc = zks.processTxn(hdr, txn);
====================================》
org.apache.zookeeper.server.ZooKeeperServer#processTxn
====================================》
org.apache.zookeeper.server.DataTree#processTxn
====================================》
org.apache.zookeeper.server.DataTree#createNode
13、基于ZooKeeper的sync实现强一致等待
14、watch监听器的类型
1、getchildren():org.apache.zookeeper.ZooKeeper.ChildWatchRegistration
2、getData():org.apache.zookeeper.ZooKeeper.DataWatchRegistration
3、exists():ExistsWatchRegistration
15、watch监听器注册代码入口
org.apache.zookeeper.ClientCnxn#finishPacket
====================================》
p.watchRegistration.register(p.replyHeader.getErr());
16、客户端回调监听器代码入口
org.apache.zookeeper.ClientCnxn.SendThread#readResponse
====================================》
eventThread.queueEvent( we );
====================================》
org.apache.zookeeper.ClientCnxn.EventThread#queueEvent
====================================》
waitingEvents.add(pair);
====================================》
org.apache.zookeeper.ClientCnxn.EventThread#run
====================================》
processEvent(event);
====================================》
org.apache.zookeeper.ClientCnxn.EventThread#processEvent
17、客户端感知到zk服务端宕机的处理代码入口
当发现zk服务端发生故障时,zk客户端调用read、write会抛出IOException异常,客户端会进行捕获处理
org.apache.zookeeper.ClientCnxn.SendThread#run
====================================》
cleanup();
====================================》
org.apache.zookeeper.ClientCnxn.SendThread#cleanup
18、leader向follower发送请求代码入口
org.apache.zookeeper.server.quorum.Leader.LearnerCnxAcceptor#run
====================================》
org.apache.zookeeper.server.quorum.LearnerHandler#run
====================================》
new Thread() {
public void run() {
Thread.currentThread().setName(
"Sender-" + sock.getRemoteSocketAddress());
try {
sendPackets();
} catch (InterruptedException e) {
LOG.warn("Unexpected interruption",e);
}
}
}.start();
====================================》
sendPackets();
====================================》
org.apache.zookeeper.server.quorum.LearnerHandler#sendPackets
====================================》
oa.writeRecord(p, "packet");
19、follower处理leader请求代码入口
org.apache.zookeeper.server.quorum.QuorumPeer#run
====================================》
org.apache.zookeeper.server.quorum.Follower#followLeader
====================================》
readPacket(qp);
processPacket(qp);