Kafka高性能架构详解(图文全面总结)

Kafka高性能架构详解(图文全面总结)-mikechen

Kafka 是一个高吞吐量、高性能的消息中间件,但是大厂经常问怎么实现的,很多同学回答不上来,下面我就全面来详解原因@mikechen

磁盘顺序写

首先,Kafka采用顺序写入,可以极大的提升性能。

什么是“顺序写入”?指的是将数据按照顺序写入磁盘,而不是随机写入。

顺序写入的操作方式,可以优化磁盘的 I/O 性能,因为磁盘连续写入的数据更快。

为什么更快呢?你需要深入了解磁盘IO的运行机制。

如下图所示:

Kafka高性能架构详解(图文全面总结)-mikechen

如果你要写入数据,首先需要磁盘“寻道”,“寻道”就是磁盘磁头移动到目标轨道。

如果采用“随机写”,需要磁头在磁盘上来回移动,增加了寻道时间,降低了性能。

而采用顺序写入,通常不需要频繁移动磁头,磁头可以沿着相同的轨道顺序写入数据,减少了寻道时间。

所以,Kafka 在磁盘上,通过追加写入日志文件,这样每次写入操作都在文件末尾进行,而不是更新文件的任意位置。

如下图所示:

Kafka高性能架构详解(图文全面总结)-mikechen

顺序写入将数据,写入到相邻的磁盘块中,保持数据的物理连续性,减少磁头移动。

顺序写入,使得数据在磁盘上的物理位置连续,从而减少了磁头移动、和等待时间,提高了写入性能。

 

零拷贝

Kafka 使用零拷贝技术,来优化数据从磁盘到网络的传输过程。

这减少了数据在内存、和磁盘之间的复制次数,从而减少了 CPU 使用率和延迟。

先来看看非零拷贝的情况,如下图所示:

Kafka高性能架构详解(图文全面总结)-mikechen

采用非零拷贝,大致流程如下:

  1. 数据读取:首先,数据从磁盘读取,到内核缓冲区(内核空间);
  2. 数据复制:其次,数据从内核缓冲区,复制到用户空间的缓冲区。
  3. 网络传输:如果数据需要通过网络传输,数据再次从用户空间复制到网络缓冲区。

数据在传输、和处理过程中,会经历多次内存复制操作。

每次复制都会消耗 CPU 资源、和内存带宽,增加了系统开销。

所以,如果想体系性能,就可以考虑使用零拷贝技术,如下图所示:
Kafka高性能架构详解(图文全面总结)-mikechen

比如:使用 sendfile 技术,可以将文件数据,从磁盘直接传输到网络套接字,而无需将数据复制到用户空间。

ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

大致工作过程,如下:

首先,传输请求

应用程序发起 sendfile 调用,请求将文件描述符中的数据发送到网络套接字;

然后,内核处理

操作系统内核,接收到 sendfile 请求后,直接在内核空间中处理数据传输。

数据从文件描述符中读取到内核缓存中,再从内核缓存中写入到网络套接字,而无需将数据拷贝到用户空间。

最后,数据传输

数据在内核空间中完成读取和写入操作,从而避免了用户空间到内核空间的多次内存复制。

 

页缓存技术

Kafka 的高性能,与操作系统的页缓存(Page Cache)密切相关,理解这一点可以帮助更深入地认识 Kafka 。

我们一起来看Kafka的写入过程,如下图所示:

Kafka高性能架构详解(图文全面总结)-mikechen

当 Kafka 生产者将数据写入主题时,这些数据首先被写入页缓存,而不是直接写入磁盘。

操作系统会将数据缓存到内存中,随后再将其异步地写入磁盘,比如:采用定期的策略等。

为什么要这样来实现呢?原因很简单:就是内存的访问速度,远快于磁盘。

通过这种机制,Kafka 利用内存的高速特性来优化数据写入,同时减少了对磁盘的直接 I/O 操作。

Kafka 通过批量操作将数据合并写入页缓存,减少了磁盘写入的次数,从而,进一步提升了系统吞吐量。

 

高效的网络设计

Kafka 使用了高效的网络协议,来减少网络开销。

比如:Kafka 的协议使用了高效的序列化和反序列化机制,减少了网络传输的数据量和处理延迟。

以及,Kafka 支持对消息进行压缩(如 :GZIP、Snappy、LZ4……. 等),通过压缩减少存储空间的占用、和网络传输的开销。

这减少了磁盘 I/O 和网络带宽的消耗,提高了总体性能。

作者简介

陈睿|mikechen,10年+大厂架构经验,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注作者「mikechen」公众号,获取更多技术干货!

后台回复架构,即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法