消息队列高手课
李玥
美团高级技术专家
52199 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 42 讲
进阶篇 (21讲)
消息队列高手课
15
15
1.0x
00:00/00:00
登录|注册

15 | Kafka如何实现高性能IO?

使用sendfile系统调用
直接从PageCache复制到Socket缓冲区
减少数据复制次数
Kafka利用PageCache提升读写性能
PageCache在内存中缓存磁盘文件
Kafka的顺序写入和读取设计
磁盘顺序读写性能优于随机读写
消费端以批为单位传递消息
Broker处理批消息的方式
Kafka的Producer异步批量发送机制
ZeroCopy技术
利用PageCache加速消息读写
顺序读写提升磁盘IO性能
批量消息提升服务端处理能力
Kafka高性能IO

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

你好,我是李玥。
Apache Kafka 是一个高性能的消息队列,在众多消息队列产品中,Kafka 的性能绝对是处于第一梯队的。我曾经在一台配置比较好的服务器上,对 Kafka 做过极限的性能压测,Kafka 单个节点的极限处理能力接近每秒钟 2000 万条消息,吞吐量达到每秒钟 600MB。
你可能会问,Kafka 是如何做到这么高的性能的?
我们在专栏“进阶篇”的前几节课,讲的知识点一直围绕着同一个主题:怎么开发一个高性能的网络应用程序。其中提到了像全异步化的线程模型、高性能的异步网络传输、自定义的私有传输协议和序列化、反序列化等等,这些方法和优化技巧,你都可以在 Kafka 的源代码中找到对应的实现。
在性能优化方面,除了这些通用的性能优化手段之外,Kafka 还有哪些“独门绝技”呢?
这节课,我来为你一一揭晓这些绝技。

使用批量消息提升服务端处理能力

我们知道,批量处理是一种非常有效的提升系统吞吐量的方法。在 Kafka 内部,消息都是以“批”为单位处理的。一批消息从发送端到接收端,是如何在 Kafka 中流转的呢?
我们先来看发送端,也就是 Producer 这一端。
在 Kafka 的客户端 SDK(软件开发工具包)中,Kafka 的 Producer 只提供了单条发送的 send() 方法,并没有提供任何批量发送的接口。原因是,Kafka 根本就没有提供单条发送的功能,是的,你没有看错,虽然它提供的 API 每次只能发送一条消息,但实际上,Kafka 的客户端 SDK 在实现消息发送逻辑的时候,采用了异步批量发送的机制。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka高性能IO技术总结 Kafka作为高性能消息队列,实现了每秒钟2000万条消息的处理能力和每秒钟600MB的吞吐量。其高性能IO实现主要包括批量消息处理、顺序读写和PageCache加速消息读写。Kafka内部采用异步批量发送机制处理消息,利用简单的存储设计和顺序读写特性提升磁盘IO性能。此外,Kafka充分利用PageCache特性,提升读取速度和间接提升写入性能。另外,Kafka服务端在消费过程中使用了零拷贝技术,减少数据复制次数,加速消费流程。这些关键技术点使得Kafka在高性能IO方面具有独特优势。读者可通过深入了解Kafka源代码,进一步理解这些优化技术的原理和落地方式,以应用于其他适合的场景和应用程序中。 这篇总结突出了Kafka的高性能IO设计中的关键技术点,包括批量处理、顺序读写、PageCache缓存和零拷贝技术,为读者提供了快速了解Kafka高性能IO特点的概览。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《消息队列高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(66)

  • 最新
  • 精选
  • Peter
    老师您好,请教个问题:在NIO中创建缓冲区时,可以创建直接缓冲区,即ByteBuffer.allocateDirect(capacity)这里的直接缓冲区是不是就是零拷贝技术?

    作者回复: 不是,这只是使用堆外内存。 所谓的零拷贝,Linux的系统调用是sendfile,在java中对应的方法是FileChannel.transferTo

    2019-10-28
    3
    62
  • 微微一笑
    老师好,有些疑问希望老师解答下: ①rocketMq有consumeQueue,存储着offset,然后通过offset去commitlog找到对应的Message。通过看rocketmq的开发文档,通过offset去查询消息属于【随机读】,offset不是存储着消息在磁盘中的位置吗?为什么属于随机读呢? ②rocketMq的某个topic下指定的消息队列数,指的是consumeQueue的数量吗? ③性能上,顺序读优于随机读。rocketMq的实现上,在消费者与commitlog之间设计了consumeQueue的数据结构,导致不能顺序读,只能随机读。我的疑惑是,rocketMq为什么不像kafka那样设计,通过顺序读取消息,然后再根据topic、tag平均分配给不同的消费者实例,,这样消息积压的时候,直接增加消费者实例就可以了,不需要增加consumeQueue,这样也可以去除consumeQueue的存在呀?我在想consumeQueue存在的意义是什么呢? 哈哈,我的理解可能有些问题,希望老师指点迷津~

    作者回复: A1:这个过程就是随机读的过程。所有对文件的读写最终都要指定一个位置,都是按位置去读。随机读和顺序读的区别是,读取的数据是不是在文件中连续的一段。 A2:是的。 A3:RocketMQ的consumerQueue文件和Kafka的index file作用是差不多的,都是log文件(保存真正的消息)的索引,消费的时候,都需要先读索引,再读log,这个方面,两者并没有什么不同。它们存储设计的真正的差异的是log文件的设计,RocketMQ每个Broker只有一组log文件,而Kafka是每个分区一组log文件,你可以想一下,这两种设计各有什么优点和缺点。 另外,随机读和顺序读并没有严格的区分,不是非黑即白的。即使是最理想的顺序读,那它读第一个字节也是需要寻址的,这是不是一次随机读呢?随机读的时候,只要不是每次只读一个字节,你在读第二个字节的时候不就是顺序读吗? 所以,不用纠结这个概念,只要我们能做到读取数据的时候,尽量读连续的整块的数据,尽量减少寻址次数,性能就会更好。

    2019-08-27
    6
    41
  • 每天晒白牙
    谢谢老师,今天讲到的点,我会在课下去读源码并写出文章

    作者回复: 期待

    2019-08-27
    25
  • 龍蝦
    Kafka Producer 调用同步 send() 成功返回,其实没法保证消息已经成功发送到 Kafka 服务器?

    作者回复: 是这样的。 在Kafka中,这个Send是一个异步方法。如果要确保发送成功,你必须在提供的回调方法中去检查发送结果。 或者你也可以调用producer.send(record).get()来同步获取发送结果。

    2019-09-11
    3
    16
  • 长期规划
    老师,如果Pagecahe在刷入磁盘前系统崩溃了,那数据就丢了吧?这样说来,即使写了文件,也不代表持久化了

    作者回复: 如果进程崩溃是不会丢数据的,如果操作系统崩溃了,确实会丢失数据。但实际上,这个几率非常小。

    2019-09-24
    9
    13
  • linqw
    1、老师有个疑问,kafka在发送时,都会在客户端进行攒一波,然后过一定的时间,或者达到一定的大小发送出去,批量发送的时候,是把一批同一个topic下的分区的消息进行批量发送么?还是不管是属于同一分区的消息都进行批量发送,broker端是不会对批消息进行拆分成每一条,那这样消费端消费到的消息不是有可能有不是订阅的分区么? 2、学习到现在,有个感想,很多事情看似很简单,但是实际再做的时候都没那么简单,很多都得持之以恒,多思考、多实践、多动手,不然的话很多都是看懂,真正在使用的时候还是不知道如何下手。把很多小事、简单的事情做好本身就不是个简单的事情,目前有个想法打算把开源rocketmq读完,代码上写上注释和理解。 3、老师我一直有个疑惑点,如何才能当上架构师了,一方面硬核实力技术过硬,有整体的大局观,老师能否以你自身的经历给我们解惑下了

    作者回复: 只有相同分区的消息才能组成同一个批消息。你的第三个问题太大了,改天有时间可以专题聊一下。

    2019-08-27
    8
    12
  • 正本·清源
    班长确实知识扎实,其实全是大学本科课本的知识在不同技术上的组合。好在这些专业课我没有逃课,哈哈

    作者回复: 我怎么记得你都逃了呢?哈哈。

    2020-03-20
    10
  • 汤小高
    老师,如果消息是先写入page cache,再由操作系统写入磁盘的话,如果刚刚写入page cache,操作系统还没来得及写入磁盘,主机宕机了,那岂不是会丢数据? 那这样卡夫卡服务本身岂不是也会存在丢数据的情况? Kafka broker是在写入page cache就给producer 回复ack 还是操作系统将page cache写入磁盘后,如果是后者,就能保证不丢数据

    作者回复: 主机宕机了,那岂不是会丢数据?是的,是存在这样的可能。 Kafka的建议是通过复制而不是刷盘来保证消息可靠性,当然你也可以配置成每条消息都同步写入磁盘log.flush.interval.messages=1,但是这样会严重降低写入性能,基本上就没法用了。

    2020-01-04
    9
  • leslie
    老师的课程学到现在开始越来越费力了:一堂课学完笔记量已经直线上升了;对于今天的课程读完后有些困惑之处烦劳老师可以指点迷津: 1.客户端发送者的发送给服务器端的时候:其实是写入一个Packge或者说一个log包,然后服务器端处理完这个包之后,作为一个批处理,处理完成后给客户端的消费者消费者解包之后依次获得处理结果;是这样么。 2.关于PageCache:刘超老师的课程中曾经提及其实消息队列主要运作在缓存层,常驻缓存就是为了节约查询时间;老师早先在开课的时候提过不同的消息队列其实特性不同,Kafka擅长或者说充分利用的是PageCache,其它如RockeMQ呢?我们如何扬长避短 主要是基于以下两方面:一方面是-其实现在大量的服务器是在云端的,无论是Amaze云、腾讯云、阿里云其实共同的特性都是CPU和IO稳定性或者使用率并非真实会引发一些看似极高的是使用率真实情况却并非有那么高,另外一方面-其实任何消息队列的推出都是基于当下,如果想基于当下的消息队列做些二次开发或者特性改进需要做些什么或者准备些什么呢?操作系统、计算机组成原理,还有什么?望老师能提点1、2. 跟着老师学到现在发现确实学好这门课可能比老师最初说的要求还要高:老师的课程跟到现在,觉得自己已经在最初的目标的路上了,谢谢老师的提点;期待老师的后续课程。

    作者回复: 对于第一点,你的理解是没问题的。 第二个问题,我的建议是,平时注重学习积累,哪怕我只是开发一个CRUD,也要认真的做好每个细节,把涉及到的知识搞清楚。而不是照葫芦画瓢跟网上抄一个能work的就行了。对于二次开发这个事儿,先解决目的的问题。不能为了二次开发而二次开发,一定是遇到一个什么问题,经过思考,二次开发是最佳的解决方案,这样才需要做二次开发。 至于涉及到哪些知识,我们这门课中讲的这些基础的东西大概率你会用到,其它的可以靠日常积累和快速学习来解决。

    2019-08-27
    9
  • 易水寒
    老师好,我有个问题一直不明白,一个文件的数据应该是分散存储在磁盘上的吧(一般不太可能会是数据的位置都是连续的),读完整个文件的数据,怎么着也是需要移动磁头的吧(假如是机械盘),那么顺序读,所谓的顺序的含义是指什么?

    作者回复: 这个取决于文件系统,一般来说文件系统存储数据的单位是block,一个文件包含若干个block,文件系统一般都会尽量把一个文件的block放在一起,所以顺序读依然会比随机读快非常多。

    2019-09-23
    4
    6
收起评论
显示
设置
留言
66
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部