Kafka请求处理流程

Kafka请求处理流程

Scroll Down

5e1440b3b016a

Kafka中是通过请求响应的方式来完成数据交互的。今天,我们来看一看Kafka从请求的发起到响应,这一过程发生了什么。

Apache Kafka自己定义了一些请求协议,用于实现各种各样的交互操作。常见的有PRODUCE 请求是用于生产消息FETCH 请求是用于消费消息 的,METADATA 请求是用于请求Kafka集群元数据 信息的。

Kafka中所有的请求都是通过 TCP 网络以 Socket 的方式进行通讯的。

Kafka是通过Reactor模式 来处理请求。

Reactor模式

Reactor是一种事件驱动模式,他的dispatcher组件接受多个输入源的请求,并且分发对应的handler来处理。

Reactor的架构如下图:

image.png

从图中可以看出,多个客户端发送请求给Reactor,Reactor有个请求分发处理线程dispatcher ,也就是图中的acceptor ,它会将多个请求下发工作线程 中处理,最终把响应send会客户端也是这个acceptor的工作。

acceptor线程只负责请求分发 ,不涉及具体的业务数据操作,因此具有很高的吞吐量工作线程 也可以根据系统的能力,来进行适当的增减,来达到动态调节系统负载 能力。

Kafka的Reactor模式

Kafka的Reactor模式架构图

image.png

SocketServer组件就相当与是dispatcher,SocketServer组件包含Acceptor线程网络线程池。网络线程池也就是上面说的工作线程池,负责具体的逻辑处理。

Kafka 提供了 Broker 端参数 num.network.threads用于调整该网络线程池的线程数。其默认值是 3,表示每台 Broker 启动时会创建 3 个网络线程,专门处理客户端发送的请求。

Acceptor线程是采用轮询方式分发请求给网络线程,这种方式有利于公平的调度处理。

网络线程拿到请求后,需要注意的是,它并不是直接就处理请求了,而是把请求放到一个共享队列里面,然后由IO 线程池,负责从该队列中取出请求,执行真正的处理。具体流程如下图

image.png

Broker 端参数 num.io.threads 控制了这个线程池中的线程数。目前该参数默认值是 8,表示每台 Broker 启动后自动创建 8 个 IO 线程处理请求。

IO线程处理完请求后,会把响应放到网络线程的响应队列中,每一个网络线程都有自己的响应队列

图上还有个Purgatory组件,在Kafka中被称为“炼狱”组件,作用是缓存延迟请求,延迟请求指的是没有满足条件不能立刻处理的请求。处理如果是RPODUCE请求,那么就是将消息写入到底层的磁盘日志中,如果是FETCH请求,就从磁盘或页缓存中读取消息。

比如,如果Broker端设置了ack=all,那么就么该请求就必须等待 ISR 中所有副本都接收了消息后才能返回,既然IO线程不能立即处理该请求,就会把这条请求放入到Purgatory中暂时存储,等待时机成熟,就会取出来继续给IO线程处理。

参考

  • 极客时间-《Kafka核心技术与实践》