zookeeper核心源码分析


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建立多少个连接呢?是有限制的,默认来说603.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

PathCacheNodeCache,给你的节点加监听器,如果说监听到了事件之后,然后得到了通知,下次他会自动给你重新注册监听器

8、zookeeper 2181服务端初始化代码入口

1org.apache.zookeeper.server.NIOServerCnxnFactory#configure
2org.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监听器的类型

1getchildren()org.apache.zookeeper.ZooKeeper.ChildWatchRegistration
2getData()org.apache.zookeeper.ZooKeeper.DataWatchRegistration
3exists()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);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值