从kafka的请求处理模型理解Reactor模式

内容总结于课程: kafka请求是怎么被处理的

扩展阅读: Scalable IO in Java

简介

Kafka 自己定义了一组请求协议,用于实现各种各样的交互操作。比如常见的 PRODUCE 请求是用于生产消息的,FETCH 请求是用于消费消息的,METADATA 请求是用于请求 Kafka 集群元数据信息的。所有的请求都是通过 TCP 网络以 Socket 的方式进行通讯的

今天主要整理一下kafka Broker 端处理请求的全流程

关于处理请求,很容易想到的两个方案:

1、单线程处理请求: 由于单线程,吞吐量极差,
2、线程池处理请求: 确实优化了很多,但是每一个线程的粒度太大,处理了连接、处理、返回等操作。
3、Reactor模式: Reactor 模式是事件驱动架构的一种实现方式,特别适合应用于处理多个客户端并发向服务器端发送请求的场景。
在这里插入图片描述
client: 客户端,多个客户端会发送请求给到 Reactor
dispatch(acceptor): Reactor 有个请求分发线程 Dispatcher,也就是图中的 Acceptor,它会将不同的请求下发到多个工作线程中处理。Acceptor 线程只是用于请求分发,不涉及具体的逻辑处理,非常得轻量级,因此有很高的吞吐量表现。而这些工作线程可以根据实际业务处理需要任意增减,从而动态调节系统负载能力。

对比到kafka中的模型图:

在这里插入图片描述
Broker端有ScoketServer组件,类似于 Reactor 模式中的 Dispatcher,也有对应的 Acceptor 线程和一个工作线程池,只不过在 Kafka 中,这个工作线程池有个专属的名字,叫网络线程池。Kafka 提供了 Broker 端参数 num.network.threads,用于调整该网络线程池的线程数。其默认值是 3,表示每台 Broker 启动时会创建 3 个网络线程,专门处理客户端发送的请求。

Acceptor线程采用轮询方式将请求公平分发到所有网络线程,防止请求处理的倾斜。

网络线程池处理请求

在这里插入图片描述
网络线程将进来的请求放入到一个共享请求队列中。Broker 端还有个 IO 线程池,负责从该队列中取出请求,执行真正的处理。如果是 PRODUCE 生产消息请求,则将消息写入到底层的磁盘日志中;如果是 FETCH 请求,则从磁盘或页缓存中读取消息。

IO线程处理的才是真正处理的逻辑。Broker通过参数num.io.threads加粗样式控制了这个线程池中的线程数。目前该参数默认值是 8,表示每台 Broker 启动后自动创建 8 个 IO 线程处理请求。

Purgatory组件: 用来缓存延迟请求,一些未满足条件不能立即执行的请求。比如设置acks=all的produce请求,需要等待收到ISR中所有的副本都持久化消息后才将请求返回,此时处理该请求的IO线程必须等待其他Broker的写入。

kafka请求分类
  • PRODUCE 和 FETCH 这类请求称为数据类请求
  • 负责更新 Leader 副本、Follower 副本以及 ISR 集合的 LeaderAndIsr 请求,负责勒令副本下线的 StopReplica 请求等为控制类请求
思考,不同类型的请求,是否需要分开处理呢?
问题:

假设我们有个主题只有 1 个分区,该分区配置了两个副本,其中 Leader 副本保存在 Broker 0 上,Follower 副本保存在 Broker 1 上。假设 Broker 0 这台机器积压了很多的 PRODUCE 请求,此时你如果使用 Kafka 命令强制将该主题分区的 Leader、Follower 角色互换,那么 Kafka 内部的控制器组件(Controller)会发送 LeaderAndIsr 请求给 Broker 0,显式地告诉它,当前它不再是 Leader,而是 Follower 了,而 Broker 1 上的 Follower 副本因为被选为新的 Leader,因此停止向 Broker 0 拉取消息。
这时,一个尴尬的场面就出现了:如果刚才积压的 PRODUCE 请求都设置了 acks=all,那么这些在 LeaderAndIsr 发送之前的请求就都无法正常完成了。就像前面说的,它们会被暂存在 Purgatory 中不断重试,直到最终请求超时返回给客户端。

个人解决:

Broker中实现一个有限队列,将控制类的请求赋予更高的优先级。存在的问题,一旦优先队列满了之后,无法处理新的控制类请求。

社区解决方案:

完全拷贝网络处理架构,将两类请求进行分离,scoket使用的不同端口,使用起来需要提供不同的listeners配置,指定哪个端口处理哪一类的请求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值