1.找到入口类. 通过DataTree.createNode 找到对应的入口类.找到很多 processor


进一步找到ZooKeeperServer.submitRequest.最终是来自于Nio或者是Netty的请求.

2.研究Processor的责任链: CommitProcessor. 实现的实现注入的地方在flower,leader,observerServer的
setupRequestProcessors()中
1.ObserverZooKeeperServer.setupRequestProcessors()  (org.apache.zookeeper.server.quorum)
   ObserverRequestProcessor->commitProcessor->finalProcessor
还有一个独立的SyncRequest类. 同步数据到磁盘. 不需要发送ack给leader. 到Observer的都需要commit.

2. FollowerZooKeeperServer.setupRequestProcessors() (org.apache.zookeeper.server.quorum)
   FollowerRequestProcessor->commitProcessor->finalProcessor
3.LeaderZooKeeperServer.setupRequestProcessors() (org.apache.zookeeper.server.quorum)
   
PrepRequestProcessor->ProposalRequestProcessor-->CommitProcessor-->ToBeAppliedRequestProcessor-->FinalRequestProcessor
PrepRequestProcessor: 生成事务相关信息,最核心的是事务id.
ProposalRequestProcessor: 投票发起 [投票接收在 learnHandler中, 其实最好对应一个recevier类 ]
CommitProcessor: 提交类. 先暂时缓存预提交信息,待集群半数通过后或者收到leader.commit信息后执行写操作. 两个队列很重要.
    LinkedList<Request> committedRequests = new LinkedList<Request>(); //缓存已集群通过的操作
    LinkedList<Request> queuedRequests = new LinkedList<Request>();   //缓存预提交的操作.
 





leader:
消息来源:
1 来自客户端直接调用 LeaderZooKeeperServer类.submitRequest
2 来自flower的转发 LearnHandler类里的Leader.REQUEST请求
proposal:
发起proposal,然后等待flower的ack(learnHandler类.class里),然后调用 Leader类.processAckcommit.
commit:    
   commitProcessor类对集群通过的操作进行提交. 同时删除预提交相关信息.
   保障了操作序列的顺序性.

flower:
  1.接受到 


1. 看leader的 netty调用 ,当是request时,执行Leader的调用链路. 发起投票,投票通过发起commit.奇怪的是先通知别人commit,然后才是自己?

OpCode.sync 这个含义是 持久化到磁盘. 会调用这个SyncRequestProcessor


flower下的commitProcessor好像没有调用 commitProcessor.processRequest 暂存请求.

只有在收到leader的commit或者sync时才会调用commitProcessor.commit ,执行真正的commit;


flower在接受到leader.proposal时先暂存到            pendingTxns.add(request);

先执行 syncProcessor.processRequest(request);{flush有两个条件,超过个数,或者没有后来者. },再执行SendAckRequestProcessor


疑惑是 机器1是主机,机器2只收到commit 2时,怎么处理这个commit;





Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐