5. 事务请求
下面将介绍在Zookeeper
中,一次事务请求的整个过程。对于非事务请求,其处理过程比较简单,则不进行介绍。对于客户端来说,其过程是一样的,客户端将请求包装进队列中,然后发往服务端。所以这里的重点是分析服务端的处理过程:
每个Client
一般都是和一个Server
保持长连,Server
一般是 Follower
、Observer
。当Leader
配置了leaderServes=true
,则客户端也可以连接到Leader
。
Server
接收到请求后,会间接交给ZookeeperServer
处理,为了将整个过程都涵盖到,因此下面假定Client
连接的是Follower
,并向Follwer
发送 createNode 的请求。
下图是事务请求的整个过程:
整体流程如下:
- FollowerRequestProcessor 接收到
Client
的请求后,会将请求交给 CommitRequestProcessor,其会判断请求是否要提交:如果需要则将请求放进针对每个sessionId区分的pendingRequests
中等待commit; - 在将请求提交给 CommitRequestProcessor 后,FollowerRequestProcessor 会将事务请求通过之前与
Leader
建立的连接 交给Leader; - Leader 在接收到请求后,交给 PrepRequestProcessor 进行处理,其会在ZK的
outstandingChanges
和outstandingCHangesForPath
里添加一条更改记录ChangeRecord
。其后将请求交给 ProposalRequestProcessor 进行处理; - ProposalRequestProcessor首先将请求提交给下一个处理器CommitRequestProcessor,然后调用
Leader.propose
来发起事务提议,也即是给每个与自己相连的Follower发从事务提议Proposal
。完成发送后调用 SyncRequestProcessor 添加事务记录,再将请求发送给AckRequestProcessor,其向Leader做出Ack应答; - Follower接收到来自Leader的提议后,交给SyncRequestProcessor添加事务记录,再将请求传递给下一个处理器SendAckRequestProcessor,其则向Leader返回ACK消息;
- Leader收到ACK信息后,会执行Leader.processAck方法,首先会取出之前提交的
Proposal
,然后进行判断是否有超过一半的Follower返回了ACK
,若是则将Proposal
放进toBeApplied
队列中,并向所有Follower发送COMMIT
提交事务(若提交的事务与本地不一致则系统会停机
),向Observer发送INFORM
并带上数据。最后执行CommitRequestProcessor.commit进行本地提交,本地提交最后执行的是Leader.processRequest
方法,其将请求最终交给FinalRequestProcessor进行处理; - FinalRequestProcessor则将事务请求应用到内存数据库中,并做一些收尾工作;
- Follower收到事务的
COMMIT
消息,提交事务,执行CommitRequestProcessor.commit
将事务变更应用到内存数据库中。