您的位置:首页 > 其它

Kafka系列(24)请求是怎么被处理的?

2019-08-17 19:39 357 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_18522601/article/details/99677431

无论是Kafka客户端还是Broker端,它们之间的交互都是通过“请求响应”的方式完成。比如,客户端会通过网络发送消息生产请求

给Broker.而Broker处理完成后,会发送响应的响应到客户端

 

PRODUCE 用于生产消息,Fetch请求用于消费消息。MetaData请求是用于请求Kafka集群元数据信息的。

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

1 顺序处理请求

  while (true) {
            Request request = accept(connection);
            handle(request);
}  通吐量太差,只适用于请求发送非常不频繁的系统。

2每个请求使用单线程处理

while (true) {
            Request = request = accept(connection);
            Thread thread = new Thread(() -> {
    handle(request);});
            thread.start();
}
每个请求都创建线程的做法开销极大,在某些场景下甚至会压垮整个服务

Kafka使用Reactor模式

 Reactor模式是事件驱动架构的一种实现方式,特别适合应用于处理多个客户端并发向服务器发送请求的场景。

 

从这张图中,我们可以发现,多个客户端会发送请求到Reactor.Reactor有个请求分发线程Dispatcher,也就是图中acceptor,

它会将不同请求下发到多个工作线程中处理。

这个机构中,Acceptor线程只用于请求分发,不涉及具体的逻辑处理,非常轻量级,因此具有很高的通吐量。而这些工作

线程可以根据实际业务处理需要任意增减,从而动态调节系统负载能力。

 

在Kafka中,这个工作线程池有个专属的名字,叫网络线程池。Kafka提供了Broker端参数num.networtk.threads,用于调整网络线程池的线程数。默认3.表示每台Broker启动会创建3个网络线程,专门处理客户端发送的请求。

 

当网络线程拿到请求后,它不是自己处理,而是将请求放入到一个共享队列中。Broker端还有一个Io线程池,负责从该队列取出请求,执行真正的处理,如果是PRODUCE 生产请求,则将消息写入到底层的磁盘日志中;如果是FETCH请求,则从磁盘或页缓存中读取消息。

IO线程池中的线程才是执行请求逻辑的线程,Broker端参数num.io.threads控制了这个线程池中线程数。目前默认是8  每台

broker启动后自动创建8个IO线程处理请求。

比如,如果你的机器上的CPU资源非常充裕,完全可以调大该参数,允许更多的并发请求被同时处理

当IO线程处理完请求后,将生成的响应发送到网络线程池的响应队列中,然后由对应的网络线程负责将REsponse返回给客户端

 

请求队列是所有网络线程共享的,而响应队列则是每个网络线程专属的。这么设计的原因在于,Dispaatcher只用于请求分发而不负责响应回传,因此只能让每个网络线程自己发送response给客户端,这些Response也就没必要放在一个公共的地方。

上图中有个Purgatory的组件,就是Kafka中著名的炼狱组件。 它是用来缓存延时请求。所谓延时请求,就是那些一时未满足条件不能立刻处理的请求。

    比如设置了acks=all 的produce请求,一旦设置了acks=all,那么该请求就必须等待ISR中所有副本都接受了消息后才能返回,此时处理该请求的IO线程就必须等待其他Broker的写入结果。当请求不能立刻处理时,它就会暂存在P

purgatory中。稍后一旦完成条件,Io线程会继续处理该请求,并将Response放入对应网络线程的响应队列中。

  有些请求不是数据类的而是控制类的,用来执行特定的Kafka内部动作的。

  Leader变成Follower副本,执行显式的日志截断

  同样是在积压大量数据类请求的Broker上,当你删除主题的时候,Kafka控制器向该Broker发送StopReplica请求。

如果该请求不能及时处理,主题操作会一直hang住。进而增加了删除主题的延时。

 KafkaBroker 启动后,会在后台分别创建两套网络线程池和Io线程池,它们分别处理数据类请求和控制类请求

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: