• 浅谈Kafka Broker 请求处理流程


    概述

    首先,无论是 Kafka 客户端还是 Broker 端,它们之间的交互都是通过请求-响应的方式完成的。Kafka 自己定义了一套请求协议,用于实现各种各样的交互操作,所有的请求都是通过 TCP 以 Socket进行通讯的。比如 PRODUCE 请求是用于生产消息的,FETCH 请求是用于消费消息的,METADATA 请求是用于请求 Kafka 集群元数据信息的。

    因为采用顺序请求的方式吞吐量太低,采用每个请求对应一个线程的方式开销太大,所以Kafka采用Reactor设计模式(1 + M + N) → 经典高并发IO设计模式 来处理请求。

    在这个架构中,Kafka Broker 端有个 SocketServer 组件,即 Reactor 模式中的 Dispatcher,它有对应的 Acceptor 线程和一个 Worker 线程池 → 叫网络线程池。Kafka 提供了 Broker 端参数 num.network.threads(默认为3),用于调整该网络线程池的线程数。

    具体流程

    1. Acceptor 采用轮询的方式将请求公平地发到所有网络线程中,当Kafka网络线程接收到请求后,他并不会顺序处理,Kafka 在这个环节又做了一层异步线程池的处理,将请求放入到一个共享请求队列中。
    2. 之后,由IO线程池负责从该队列中取出请求,执行真正的处理,Broker 端参数 num.io.threads(默认为8→如果CPU资源充足可以适当调大) 控制了这个线程池中的线程数。如果是 PRODUCE 生产请求,则将消息写入到底层的磁盘日志中;如果是 FETCH 请求,则从磁盘或页缓存中读取消息。
    3. 当 IO 线程处理完请求后,会将生成的响应发送到网络线程池的响应队列中,然后由对应的网络线程负责将 Response 返还给客户端。
    4. 如果是延时请求(一时未满足条件不能立刻处理的请求 → 设置acks=all的PRODUCE请求)的话,还需要在进入响应队列之前先进入 Purgatory 炼狱组件中等待,

    可以看到,Kafka中的Reactor是经典的1(监听) + M(读写) + N(业务逻辑)的设计模式。

    在这里插入图片描述
    图引自胡夕老师《Kafka核心技术与实战》极客时间专栏

    其中的细节

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

    参考自胡夕老师《Kafka核心技术与实战》极客时间专栏,老师的课很棒,强烈推荐!

  • 相关阅读:
    TVP 专家谈腾讯云 Cloud Studio:开启云端开发新篇章
    MongoDB基础知识~
    uni-app 小程序:显示图片并且点击图片展示大图
    TypeScript(7)泛型
    CSS---关于font文本属性设置样式总结
    shap库源码和代码实现
    个股期权、商品期权、股指期权开户攻略(全网最全)
    字节前端实习一面
    vue中预览epub文件
    Spring入门程序(二)
  • 原文地址:https://blog.csdn.net/qq_39598180/article/details/125622275