ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# 请求处理 * Apache Kafka 自定义了一组请求协议 * 所有请求都是通过 TCP 以 Socket 的方式通讯 Kafka Broker 处理请求的全流程 * 顺序处理请求 ``` Java while (true) { Request request = accept(connection); handle(request); } ``` * 缺陷:吞吐太差 --- * 每个请求使用单独线程处理 ``` Java while (true) { Request = request = accept(connection); Thread thread = new Thread(() -> { handle(request);}); thread.start(); } ``` * 优点:吞吐大 * 缺点:资源开销大 * 适合请求发送频率低的场景 --- * Kafka 使用 Reactor 模式 Reactor 模式 * Reactor 模式是事件驱动架构的一种实现方式 * 适合应用于处理多个客户端并发向服务器端发送请求的场景 * 参考:[http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf](http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf) ![](https://img.kancloud.cn/65/4b/654b83dc6b24d89c138938c15d2e8352_1950x627.png) * 多个 Clients 发送请求到 Reactor * Reactor 的请求分发线程 Dispatcher,i.e. Acceptor 将不同的请求下发到多个 worker 线程中 * Acceptor 只涉及分发,因此有很高的吞吐 * Worker 线程根据业务需求可以任意增减,动态调节系统负载能力 ![](https://img.kancloud.cn/e1/ae/e1ae8884999175dac0c6e21beb2f7e6e_1950x847.png) * Kafka Broker 端参数 `num.network.threads` 调整网络线程池的线程数,默认为 3 * Acceptor 线程通过轮询方式将入站请求公平的发送到所有网络线程中 ![](https://img.kancloud.cn/d8/a7/d8a7d6f0bdf9dc3af4ff55ff79b42068_1950x1153.png) * 当网络线程拿到请求后,不是自己处理,而是放到一个共享请求队列中 * Broker 端 IO 线程池负责从该队列中取出请求,执行真正处理 * 如果是 Produce 请求,将消息写入到底层的磁盘日志中 * 如果是 Fetch 请求,则从磁盘或页缓存中读取消息 * IO 线程池中的线程是执行请求逻辑的真正线程 * Broker 端参数 `num.io.threads` 控制了该线程池中的线程数,默认值为 8 * IO 线程处理完后,将 response 发送到网络线程池的响应队列中 * 由对应的网络线程负责将 response 返回给 client * 请求队列是所有网络线程共享,响应队列是专属的 Purgatory 组件 * 职责:缓存延时请求(Delayed Request) * 延时请求:一时未能满足条件不能立刻处理的请求 * e.g. acks=all 的 Produce 请求 需要等待 ISR 中所有的副本都接收了消息才能返回,此时处理该请求的 IO 线程必须等其他 Broker 写入结果 请求分类 * 数据类请求:Produce、Fetch 这类请求 * 控制类请求:LeaderAndLsr、StopReplica