问题
带着问题撸源码系列-zookeeper-客户端发写请求,最终怎么通过2PC同步到集群所有机器?
猜测
we all know the 2PC, but how exactly does it work?
理论上,就是leader接收到请求,然后发给Prepare,让小伙伴们准备好,过半数人回复ok了之后,leader回复客户端,然后再发Commit请求让小伙伴们真正提交
流程图镇楼
看源码画图不易,且行且珍惜
源码
Follower接收到客户端的写请求,会先根据责任链调下一个Processor,然后把写请求转发给Leader。
leader接收到转发的写请求,然后会怎么样?那就得研究Leader的责任链了。。
所以我们先找Leader的责任链:
org.apache.zookeeper.server.quorum.LeaderZooKeeperServer
上来文件头部的注释就有相关的说明了:
/**
*
* Just like the standard ZooKeeperServer. We just replace the request
* processors: PrepRequestProcessor -> ProposalRequestProcessor ->
* CommitProcessor -> Leader.ToBeAppliedRequestProcessor ->
* FinalRequestProcessor
*/
PrepRequestProcessor -> ProposalRequestProcessor -> CommitProcessor -> Leader.ToBeAppliedRequestProcessor -> FinalRequestProcessor
所以我们可以从PrepRequestProcessor
开始看了:
不断地从submittedRequests
中取Request。最后调用pRequest(request)
,来到下一个Processor,断点打起来~
ProposalRequest
走else逻辑直接调用了nextProcessor
那就到CommitProcessor
因为是写请求,走if分支,QueuedWriteRequest
队列中加入了请求。
断点调试
server1、2、3顺序启动,server2是leader,debug方式启动server2
client连到server2,直接给leader发请求 create /t2
!!!!!!!这里要特别注意,在调试的过程中我们启动的server2本来是leader的,调试经常导致断线,断线之后server2就不是leader了,得特别注意!
为了避免这种情况,我们把server3干掉;这样,如果server2超时,只剩下server1,无法对外提供服务;server2活过来的话仍然是leader
先来到PrepRequestProcessor
责任链到下一个Processor
来到ProposalRequestProcessor
调用责任链下一个Processor,来到CommitProcessor
请求加入到pendingRequests
来到Leader,发送Propose请求
点收选票,这时候收到了来自与自己和server1的ack
然后来到了leader的commit
再从pendingRequest中取出了我们的请求
来到Leader#ToBeAppliedRequestProcessor
最后来到FinalRequestProcessor#processRequest
zks.processTxn(request)
一路往下调用:
来到最底层的createNode()
我们可以看到这些其实都只是写到内存里。那么是怎样写到硬盘里的呢?后文继续分析:带着问题撸源码系列-zookeeper-如何把内存数据写到硬盘?
回答问题
理论是正确的!
参考
http://www.guobingwei.tech/articles/2019/04/01/1554076444476.html