后端工程师的高阶面经
邓明
前 Shopee 高级工程师,Beego PMC
6888 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
后端工程师的高阶面经
15
15
1.0x
00:00/00:00
登录|注册

29|高性能:Kafka 为什么性能那么好?

你好,我是大明。今天我们来讨论一个问题,Kafka 的性能为什么那么好?
Kafka 的高性能话题也算是热点了,如果你面试的公司在并发量或者数据量上已经到了一定地步,那么面试的时候大概率逃不过这个问题。
大部分人面不好这个部分的原因只有一个:Kafka 为了实现高性能采用的手段太多了,以至于根本记不住。那么这一节课我就先聚焦在 Kafka 本身为了高性能做了哪些事情,下一节课我再从实践出发,告诉你怎么优化 Kafka 的性能。
让我们先从 Kafka 的一些基本知识开始说起。

Kafka 分段与索引

即便在同一个分区内部,Kafka 也进一步利用了分段日志和索引来加速消息查找。在 Kafka 内部,一个分区的日志是由很多个段(segment)组成的,每个段你可以理解成一个文件。同一个 topic 的文件就存放在以 topic 命名的目录下。
为了快速找到对应的段文件,段日志文件使用了偏移量来命名。假如说一个文件的名字是 N.log,那么就表示这个段文件里第一条消息的偏移量是 N + 1。
这里你就能猜到,Kafka 完全可以根据文件名来进行二分查找,从而快速定位到段文件。
为了加快段文件内的查找,每一个段文件都有两个索引文件。
一个是偏移量索引文件,存储着部分消息偏移量到存储位置的映射,类似于 <offset, position> 这种二元组。这个 offset 不是全局 offset,是相对于这个文件第一条消息的偏移量。也就是说假如第一条消息的全局偏移量是 1000,那么偏移量为 1002 的消息的索引项是 <2, pos1>
一个是时间索引文件,存储着时间戳到存储位置的映射,类似于 <timestamp, position> 二元组。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka高性能原因总结 Kafka的高性能得益于多种优化手段,包括分段与索引、零拷贝和批量操作。首先,Kafka利用偏移量和时间索引文件实现快速消息查找,同时应用零拷贝技术减少内核态与用户态的切换,提高性能。此外,批量操作减少了系统调用和内核态与用户态的切换,高效利用网络带宽。Kafka还充分利用了page cache,将数据写入page cache而不是直接刷新到磁盘上,有效减少了真实的IO操作次数。此外,Kafka充分利用了顺序写的特性,针对每一个分区有一个只追加的日志文件,提高了写入性能。然而,分区过多可能导致性能下降,因此需要合理规划分区数量。最后,Kafka的分区机制也能提高性能,减少并发竞争。整体而言,Kafka的高性能源自其多方面的优化策略,使其成为一款性能出色的消息中间件。 Kafka还采用了批量处理来提高性能。Kafka的客户端在发送的时候,并不是说每来一条消息就发送到broker上,而是说聚合够一批再发送。而在broker这一端,Kafka也是同样按照批次来处理的,显然即便同样是顺序写,一次性写入数据都要比分多次快很多。批量处理能够提升性能的原因是非常直观的,有两方面。一方面是减少系统调用和内核态与用户态切换的次数。另外一方面,批量处理也有利于网络传输。在网络传输中,一个难以避免的问题就是网络协议自身的开销。比如说协议头开销。那么如果发送100次请求,就需要传输100次协议头。如果100个请求合并为一批,那就只需要一个协议头。 Kafka为了进一步降低网络传输和存储的压力,还对消息进行了压缩。这种压缩是端到端的压缩,也就是生产者压缩,broker直接存储压缩后的数据,只有消费者才会解压缩。它带来的好处就是,网络传输的时候传输的数据会更少,存储的时候需要的磁盘空间也更少。当然,缺点就是压缩还是会消耗CPU。 总的来说,Kafka的高性能源自多方面的优化策略,包括分段与索引、零拷贝、批量处理和消息压缩等技术手段。这些优化策略使Kafka成为一款性能出色的消息中间件,为高并发和大数据场景提供了可靠的消息传输和存储解决方案。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端工程师的高阶面经》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(11)

  • 最新
  • 精选
  • 陈斌
    老师这节课讲的很好,之前也看过其他人讲过Kafka为什么性能高,但是都讲的不全面,学习到了。 page cache 技术,MySQL、 Redis、Elasticsearch 也用到了。 顺序写 Hive、Spark、ClickHouse 都使用到了。 零拷贝 技术 Netty, RocketMQ肯定使用到了。 分区可以用来缩小并发粒度,减轻并发竞争: JDK1.8 之前实现的 ConcurrentHashMap 版本。HashTable 是基于一个数组 + 链表实现的,所以在并发读写操作集合时,存在激烈的锁资源竞争,也因此性能会存在瓶颈。而 ConcurrentHashMap 就很很巧妙地使用了分段锁 Segment 来降低锁资源竞争

    作者回复: 赞!在面试中要记得这种横向对比的面试技巧!

    2023-08-23归属地:广东
    1
  • KK
    请问老师一个问题:kafka 多分区,在写入的时候,是同时写入多个分区吗?还是只写主分区,然后同步到从分区?

    作者回复: 这个是和你的生产者的 acks 设置有关的。如果你选择要同步到从分区,那么就是写主分区,然后同步到从分区之后,才算是写入成功了。

    2023-11-03归属地:北京
  • KK
    “可以确定 20000 这条消息应该放在 010031.log 这个文件里面。”,这里的20000是不是写错了,应该是2000? 根据描述:假如说一个文件的名字是 N.log,那么就表示这个段文件里第一条消息的偏移量是 N + 1。

    作者回复: 我应该没写错吧?这里就是整个偏移量是 20000,010031 的第一条应该是 10032,20000 在这个文件。

    2023-11-03归属地:北京
    2
  • Lum
    锁分离(Lock Separation):在高并发环境下,锁竞争可能会成为瓶颈。锁分离是一种将锁拆分成多个细粒度锁的技术,以减少锁竞争和提高并发性能。例如,在数据库中,可以将表锁拆分为行锁或列锁。 数据分片(Data Sharding):数据分片是一种将数据拆分成多个分片的技术,以提高并发性能和可扩展性。每个分片可以独立处理请求,从而减少竞争和提高吞吐量。例如,在分布式数据库中,可以将数据按照某种规则(如哈希或范围)划分到不同的节点上。 缓存(Caching):缓存是一种将数据存储在内存中,以加速读写操作和减少对后端存储系统的访问的技术。例如,在 Web 应用中,可以使用缓存来缓存页面、结果集或对象,以减少数据库访问和提高响应速度。 异步处理(Asynchronous Processing):异步处理是一种将请求和响应分离的技术,以提高并发性能和可扩展性。例如,在 Web 应用中,可以使用异步 Servlet 或异步消息处理器来处理请求,从而释放线程资源和提高吞吐量。 无锁编程(Lock-free Programming):无锁编程是一种不使用锁的并发编程技术,以减少竞争和提高性能。例如,在并发数据结构中,可以使用无锁算法(如 CAS)来实现原子操作,从而避免锁竞争和死锁。

    作者回复: 赞赞赞!如果是面试的话,比较建议用自己业务的例子,这样会有更好的说服力。

    2023-10-27归属地:北京
  • Geek_icecream
    老师在讲解“零拷贝”时,提到的“四次内核态与用户态的切换”那张图里面,出现了两次“系统调用写操作”,是不是写错了?在进行第一次用户态与内核态切换时,不应该是“系统调用读操作”吗?先将内核态的数据“读”到用户态

    编辑回复: 多谢提醒,已经改好啦🌹

    2023-10-17归属地:广东
    2
  • ZhiguoXue_IT
    请教一下老师,kafka高性能的原因是这些,阿里的rocketmq的高性能有相似的吗

    作者回复: 基本类似,但是我研究不够深入,哈哈哈,没怎么看过源码。

    2023-09-29归属地:北京
  • Geek_43dc82
    发现了一些语言层面为了减少并发粒度的,减少锁并发竞争的优化,比如Golang GMP调度模型中的有global queue还有每个P本地的queue,实际P本地的queue的存在也是为了减少并发竞争

    作者回复: 赞!这就是典型的全局竞争优化为局部竞争!

    2023-09-20归属地:北京
  • 五号特派员
    请问老师kafka和pulsar对比如何呢

    作者回复: 问到我的知识盲区了,我没怎么用过 plusar。之前我做技术选型的时候,我差不多就是无脑选 Kafka。

    2023-09-13归属地:四川
  • peter
    请教老师几个问题: Q1:应用进入内核态,以Java为例,是什么语句? 文中有这一句:“这一步应用就是发了一个指令,然后是 DMA 来完成的”,这里的“应用发指令”,从Java代码的角度,什么代码的效果是普通的两次拷贝?什么代码可以做到零拷贝(即该代码可以控制DMA来完成数据拷贝)? (附:如果是C语言,又是哪一个语句?这个和专栏有点距离,可以不答) Q2:kafa是用Java写的,kafka可以控制Page Cache,那么,什么Java代码可以控制Page Cache? Q3:kafka的批量处理,是可以设置的吗?比如:是否采用批量处理,批量处理的数量等。应用可以设置吗? Q4:电商的topic按什么分类? 比如京东,首页左边是商品分类,会按商品类型来设置topic吗? Q5:生产者和消费者的压缩,并不是应用压缩,而是kafka客户端的压缩,对吗? 即生产者和消费者的开发人员并不需要开发压缩、解压缩功能,而是调用kafka的客户端的库,由库来完成压缩和解压缩功能。 Q6:kafka功能强大,那其他三种MQ就没有必要用了,只选kafka就可以了。是这样吗?

    作者回复: 1. 在 JAVA 层面上其实你是感知不到的,你只知道你调用了一个JAVA 方法。如果这个 JAVA 方法最终在 JDK 里面发起了系统调用,那么你就要进入内核态了。在 Java 里面有一部分方法都是依赖native 方法来实现的。 2. 说起来,这就是我的知识盲点了,以前JAVA我也没直接操作过 Page Cache,但是我之前记得就是有不同的文件相关的 OutputStream 实现,就是没特意写明就是写到了 page cache。 3. 都是可以设置的。 4. 这个每个公司,甚至一个公司的不同部门设计方案都不一样,要看具体的场景。这个topic 和商品分类没什么关系,一般是指什么业务场景。 5. 对的 6. 也不是,因为别的 MQ 有一些 Kafka 没有的功能。不过如果你技术选项,无脑选 Kafka 就是了。这样做最大的好处就是,万一出问题了,别人也不能说 kafka 选得不对。

    2023-08-23归属地:北京
  • Johar
    不过之前阿里云中间件团队测试过,在一个 topic 八个分区的情况下,超过 64 个 topic 之后,Kafka 性能就开始下降了。 老师,这个测试数据是部署了多少broker节点?换句话说,一个broker节点分配多少分区比较合适?

    作者回复: 我给你找找原文,应该是这篇 https://developer.aliyun.com/article/62832。 我个人的话对一个 Broker 节点该分配多少分区,没有研究,这个得去找 Kafka 运维的同学了解一下了。

    2023-08-23归属地:重庆
收起评论
显示
设置
留言
11
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部