写点什么

面试官问:Kafka 为何有如此高的吞吐量和性能

用户头像
面试官问
关注
发布于: 2021 年 03 月 14 日

面试官问:简历中写到曾经使用 Kafka 作为消息中间件,我们知道,Kafka 是将数据保存到磁盘中的,那么它为何还能够具备如此高的吞吐量和性能呢?


旁白:Kafka 作为消息中间件的常用选型,在项目中很多场景都会使用到,也是大数据领域的一个基础组件,面试中必然少不了会被问到相关问题。


候选人:在大多数人的固有印象中,写磁盘肯定比写内存要慢很多,而 Kafka 却选择写磁盘还能够获取高吞吐量和性能的关键原因主要是使用顺序写磁盘(sequence IO)代替随机写磁盘。我们知道,出于硬件资源成本考虑,大多数服务器的存储是使用传统的机械硬盘(HDD),而不是固态硬盘(SSD)。机械硬盘的缺点需要从它的远离说起,它在读写数据时,首先读写磁头需沿径向移动,移到要读取的扇区所在磁道的上方,磁头到达指定磁道后,通过盘片的旋转,使得要读取的扇区转到读写磁头的下方,最后才是读写数据,寻道和旋转占用了磁盘读写的大量时间。而 Kafka 正是通过顺序写的方式,来减少寻道和旋转时间,进而规避了磁盘读写慢的问题。


面试官:那即使是顺序写磁盘,由于磁盘的读写速度天然比内存慢很多,那 Kafka 是如何解决这个问题的呢?


候选人:这个问题的解决主要是依赖于操作系统的页面缓存(PageCache)机制,以 Linux 为例,Linux 会将磁盘中的一些数据读取到内存中,称之为 PageCache。读写磁盘的时候都是优先对 PageCache 进行读写。其中,读数据时就是将 PageCache 当作缓存,直接从中读取数据;写数据时也是先写入到 PageCache 中,但 PageCache 中的数据并不会实时刷新到磁盘中,只有当 PageCache 中的脏页到达一定比例之后,Linux 操作系统才会把数据刷到磁盘当中。在机器发生掉电的时候,会出现脏数据。PageCache 同时可以避免在 JVM 内部缓存数据,避免不必要的 GC 以及内存空间占用。


面试官:那脏数据的问题如何解决呢?


候选人:这种问题一般都是通过分布式(副本)的方式将数据写入到多台机器上来规避的。


面试官:上面我们是从读写磁盘方面聊了 Kafka 如何实现高吞吐量,那 Kafka 作为一个消息队列,最核心的功能就是收发消息了,那在这方面 Kafka 做了哪些事情来实现高性能的呢?


候选人:Kafka 数据的收发底层主要是网络 I/O,以数据发送为例,传统的网络 I/O 流程如下:


  • 操作系统从磁盘把数据读到内核区

  • 用户进程把数据从内核区拷贝到用户区

  • 用户进程再把数据写入到 socket,数据流入内核区的 Socket Buffer 中

  • 数据从 Socket Buffer 中发送到到网卡,这样完成一次数据发送


可以看到,同一份数据在内核 Buffer 与用户 Buffer 之间拷贝了两次。而 Linux 操作系统提供了零拷贝机制,它使用了 sendfile 方法, 允许操作系统将数据从 Page Cache 直接发送到网络,避免了数据在内核区和用户区之间的拷贝,进而大幅提升性能。

拓展阅读



本文首发于同名微信公众号:面试官问,原文链接:面试官问:Kafka 为何有如此高的吞吐量和性能

关于我

微信公众号:面试官问,原创高质量面试题,始于面试题,但不止于面试题。


发布于: 2021 年 03 月 14 日阅读数: 27
用户头像

面试官问

关注

还未添加个人签名 2017.10.20 加入

还未添加个人简介

评论

发布
暂无评论
面试官问:Kafka 为何有如此高的吞吐量和性能