在分析HBase服务端处理rpc请求的流程之前,先简单地介绍一种高性能的I/O设计模式,即Reactor模式。
系统I/O可分为阻塞型,非阻塞同步型以及非阻塞异步型三种,阻塞/非阻塞是对调用者发出调用请求之后的状态而言,在阻塞型I/O中只有调用操作结束之后控制权才会回到调用者手里,这意味着调用者在这段时间做不了其它事情,只能等待调用操作的结果返回。而所谓同步/异步是对调用操作的返回方式而言,在同步模型中,调用操作在没有得到结果之前是不会返回的,也就是说调用操作一旦返回就带上了请求结果。异步模型正相反,调用请求发生之后,调用操作就直接返回了,所以并没有调用结果,后续会通过回调函数或状态、通知等方式将结果通知给调用者。
Reactor模式是建立在上述概念基础上的一种高性能I/O多路复用方法。下图是Reactor模式的基本模型图:
从图中可以知道,Reactor首先基于事件驱动,包含了一个或多个读写输入源,中间的Service Handler是基于I/O复用机制的事件分离器,用于将读写源输入的请求(Event)分发给相应的事件处理者(Request Handler)。基于此,开发人员在开始的时候就需要在Service Handler中注册感兴趣的事件,并提供相应的事件处理者,以便事件分离器在合适的时机将请求分发给对应的Request Handler。
HBase的Rpc服务端采用了Reactor模型,主线程Listener负责accept外部链接connection,Listener包好了多个子线程Reader和一个Selector,这些Reader通过Selector轮询接收Listener监听到的连接,并将请求重构成call对象实例,添加到call queue中,再由call queue交给后面的Handler线程处理,Handler线程发起发射调用,并将response数据交给Responder线程处理,Responder线程将数据最终写回给client端。引用一张图总结上述几个组件的关系如下所示(图片出处链接):