ZooKeeper集群中的跟随者对客户端请求的处理流程解读(三)

jopen 4年前

前篇简要回顾:前篇文章讲到了ZK在回复完成之后进入了接客状态,跟随者在监听客户端端口的部分接收到客户端的请求数据包,然后开始对这个包进行处理,接下来进入了ZK对客户端请求处理流程的核心部分。。。


本篇从ZooKeeperServer的 processPacket这个方法开始讲起,也就是客户端连接实例ServerCnxn会把数据包递交给ZooKeeperServer的 processPacket方法,processPacket将数据包装成ZK请求最后递交到了processPacket方法来继续处理:

看到实际上由ZooKeeperServer关联的第一个客户端请求处理器来处理的,这里讲一下跟随者的客户端请求处理器链。


ZooKeeperServer定义了一个模板方法setupRequestProcessors,不同角色类型的ZK节点会有不同的实现,这里我么你看一下跟随者是如何实现这个方法来构造客户端请求处理器链的:

根据上面的处理器构造链逻辑,画出了下面的处理器链模型,可以看到ZK跟随者对客户端的处理器链有两条。

我 们先看看第一条链,SyncRequestProcessor处理器主要是用来处理ZK日志的,SyncRequestProcessor接收到日志请求 会首先将日志递交给SyncRequestProcessor实例维护的等待队列里面,另外SyncRequestProcessor的主线程会从这个队 列里面拿到日志请求来处理,这里主要是将ZK事务日志写入ZK的日志存储结构,随后SyncRequestProcessor将日志请求包传递给 SendAckRequestProcessor处理器,由SendAckRequestProcessor处理器来发送日志写入的确认报文。


下 面来看看第二条处理器链,首先客户端请求报文会递交给FollowerRequestProcessor这个处理器,这个处理器做的事情是首先将包递交给 下一个处理器的等待处理队列,也就是CommitProcessor的等待处理队列,然后判断请求的类型,这里对sync类型的请求处理有点不同,ZK作 者解释的意思是我们需要跟踪当前跟随者挂起的同步操作,因此需要将同步操作记录下来,实现是放入跟随者关联的一个同步队列里面。我们接续看跟随者是如何处 理客户端请求报文的,这里FollowerRequestProcessor会将写请求转发给Leader,如果是读请求则直接交给下一个请求处理器即 FinalRequestProcessor来处理。


另外提一下CommitProcessor主要维护两个队列,queuedRequests和committedRequests:

queuedRequests用来存放客户端的请求,包括读、写、同步请求,处理的时候从这个队列里面拿数据,如果是读请求,则直接交给下一个处理器,如果是写请求或者同步请求,则挂起,等待Leader的确认。

committedRequests主要用来存储Leader反馈的提交请求,即Leader确定之前挂起的某个客户端请求可以提交了。


FinalRequestProcessor做的事情主要是客户端请求处理的最后一个阶段,如果是读请求则将数据读取返回给客户端,如果是写请求则将数据写入ZK,如果是同步请求则则将同步后的数据返回给客户端。


这里画出一张图表示一下跟随者对客户端请求的处理行为:

FollowerRequestProcessor的处理流程。


CommitProcessor的处理流程。

到这里,跟随者对客户端的请求处理流程大致已经清楚,这其中涉及到一些跟领导者的通信部分以及一些细节,下面讲领导者对客户端的请求处理流程解读的时候会拿出来回顾一下。

来自:http://jvmplus.duapp.com/blog/view/B143730149