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

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

你好,我是胡夕。今天我要和你分享的主题是: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 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(76)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    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之外没有特别好的解决方案。

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

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

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