Kafka 核心技术与实战
胡夕
Apache Kafka Committer,老虎证券技术总监
52815 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
结束语 (1讲)
Kafka 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

24 | 请求是怎么被处理的?

Purgatory组件
IO线程池
网络线程池
请求分发线程Dispatcher
Reactor模式
Kafka使用的是Reactor模式
每个请求使用单独线程处理
顺序处理请求
开放讨论
小结
控制类请求和数据类请求分离
Kafka是如何处理请求的?
处理请求的2种常见方案
Kafka的请求是怎么被处理的?
参考文章

该思维导图由 AI 生成,仅供参考

你好,我是胡夕。今天我要和你分享的主题是:Kafka 请求是怎么被处理的。
无论是 Kafka 客户端还是 Broker 端,它们之间的交互都是通过“请求 / 响应”的方式完成的。比如,客户端会通过网络发送消息生产请求给 Broker,而 Broker 处理完成后,会发送对应的响应给到客户端。
Apache Kafka 自己定义了一组请求协议,用于实现各种各样的交互操作。比如常见的 PRODUCE 请求是用于生产消息的,FETCH 请求是用于消费消息的,METADATA 请求是用于请求 Kafka 集群元数据信息的。
总之,Kafka 定义了很多类似的请求格式。我数了一下,截止到目前最新的 2.3 版本,Kafka 共定义了多达 45 种请求格式。所有的请求都是通过 TCP 网络以 Socket 的方式进行通讯的
今天,我们就来详细讨论一下 Kafka Broker 端处理请求的全流程。

处理请求的 2 种常见方案

关于如何处理请求,我们很容易想到的方案有两个。
1.顺序处理请求。如果写成伪代码,大概是这个样子:
while (true) {
Request request = accept(connection);
handle(request);
}
这个方法实现简单,但是有个致命的缺陷,那就是吞吐量太差。由于只能顺序处理每个请求,因此,每个请求都必须等待前一个请求处理完毕才能得到处理。这种方式只适用于请求发送非常不频繁的系统
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka请求处理流程采用Reactor模式,通过请求/响应方式完成客户端与Broker端的交互。Kafka定义了多种请求格式,通过TCP网络以Socket方式通讯。处理请求的常见方案有顺序处理和每个请求使用单独线程处理,但它们吞吐量较差。Kafka采用Reactor模式,类似于事件驱动架构,通过Acceptor线程和工作线程池实现请求分发和处理。网络线程将请求放入共享队列,由IO线程池执行实际处理,处理完后将响应发送到网络线程的响应队列。Purgatory组件用于缓存延时请求。这种处理方式能够提高吞吐量和动态调节系统负载能力。 文章详细解析了Kafka Broker端处理请求的全流程,让读者了解Kafka是如何处理请求的。此外,文章还介绍了Kafka内部控制类请求和数据类请求的分离,以及社区对此问题的解决方案。控制类请求具有特殊能力,可以直接令数据类请求失效,因此对其处理方式需要特别考虑。在2.3版本中,社区实现了数据类请求和控制类请求的分离,通过创建两套网络线程池和IO线程池的组合来分别处理这两类请求,从而解决了优先级队列方案中队列已满的问题。 总的来说,本文详细介绍了Kafka Broker请求处理流程,强调了从请求的维度去思考Kafka的工作原理对于日后执行Kafka性能优化的重要性。读者通过本文可以快速了解Kafka请求处理的全流程,以及社区对控制类请求和数据类请求分离的解决方案,为读者深入理解Kafka的工作原理提供了重要参考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kafka 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(76)

  • 最新
  • 精选
  • 朱东旭
    胡老师您好,为什么有时候听到epoll,有时候听到reactor,这俩有啥区别。。

    作者回复: 不是一个层级的东西。epoll是一种IO模型,而Reactor是一种IO处理模式(IO pattern)。可以这么说:我们可以使用epoll来实现Reactor

    2019-11-02
    6
    54
  • 明翼
    有两种方法:1 是直接替换数据处理队列中的最前面的数据进行处理,处理完控制队列,再将这个消息插队到队头;2 双队列设计,不过双队列,如果先处理控制消息,如果一直来控制消息,数据队列的消息岂不会被延迟很大; 关于复制一套,我看了下面评论,我和部分网友的理解不一样,我觉得是复制一套网络线程持+中间队列+IO线程池;也就是有两个网络线程池,+2个中间队列,和2套IO线程持; 网络线程池作用将数据分发到中间队列,和接受IO线程池的处理结果回复给客户端。我理解为什么要加这个中间队列是为了将网络处理的线程数和IO处理的线程数解耦,达到高性能和资源少占用的目的。

    作者回复: 我觉得不错:)

    2019-07-28
    30
  • 蛋炒番茄
    请求队列是所有网络线程共享的,而响应队列则是每个网络线程专属。为什么这样设计,原因没看懂。希望老师讲详细一点

    作者回复: 原因就是没必要放在一起,让各自线程自己发送就可以了。类似于:有了任务大家一起分,做完了自己单独汇报就行了

    2019-08-28
    10
    17
  • MasterSong
    很自然的一种想法是在队列中预留部分空间给控制消息,比如队列空间达到95%时对于数据消息视作队列已满,但控制消息仍然可以入队

    作者回复: 的确是一种思路~

    2020-05-13
    13
  • 拾光
    为什么不直接将Acceptor线程收到的请求存入共享队列,而要引入网络线程池来存?

    作者回复: 我认为就是单纯地想要在做一层生产者-消费者分离

    2019-12-03
    9
    12
  • 旭杰
    当 IO 线程处理完请求后,会将生成的响应发送到网络线程池的响应队列中,然后由对应的网络线程负责将 Response 返还给客户端。这个响应队列不是网络线程池共享的吗?还是说IO线程指定网络线程来发送响应?

    作者回复: 每个网络线程创建自己的响应队列。 “IO线程指定网络线程来发送响应” --- 严格来说不算是IO线程指定的,因为Kafka会记录请求是被哪个网络线程接收的,因此发送response时还会发往那个网络线程。

    2020-02-19
    6
    10
  • Mick
    老师麻烦帮我看下这个请求流程图我画的对不对?https://www.processon.com/view/link/5d481e6be4b07c4cf3031755

    作者回复: 我觉得挺好的:)

    2019-08-05
    3
    10
  • ban
    老师,社区完全拷贝了这张图中的一套组件,实现了两类请求的分离。也就是说,Kafka Broker 启动后,会在后台分别创建网络线程池和 IO 线程池,它们分别处理数据类请求和控制类请求。 上面这段话不太懂,意思是说:分别建立两套组件(A套 网络线程池IO线程池:负责处理数据类请求)、(B套 网络线程池IO线程池:负责处理控制类请求),这样理解对吗?

    作者回复: 嗯嗯,差不多是这个意思

    2019-07-28
    10
  • 王帅
    老师,你好。我在使用kafka-2.11_0.11.0.1的时候遇到了一个问题,kafka服务端由于文件打开数过多导致出现too many open files重启。但是查看kafka端口使用情况只有1.3w+.通过lsof查看sock占用数达到了6W+。(我配置的最大链接数是65536)。查看监控发现是已分配的socket的数目比较高。能不能帮忙解答下。

    作者回复: 看一下是否存在大量的CLOSE_WAIT。之前在社区的确是碰到过这种海量CLOSE_WAIT撑爆了连接数的情形。如果是,目前除了无脑增加ulimit -n之外没有特别好的解决方案。

    2020-04-11
    4
    9
  • Sunney
    老师您好,这两天做项目遇到一个问题想咨询一下,对于网络摄像头的视频流数据和抓拍到的照片数据,kafka应该如何传输呢?

    作者回复: 相同的方法,都要传输字节数组。你需要找到合适的方法把你的视频流数据或照片编码成字节序列。当然Kafka其实并不适合传输特别大的消息,因此你可以评估一下是否真的需求传视频本身?

    2019-07-29
    5
    7
收起评论
显示
设置
留言
76
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部