持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
Kafka极限的性能压测,Kafka单个节点的极限处理能力接近每秒钟 2000 万条消息,吞吐量达到每秒钟600MB。
Kafka 如何实现高性能 IO?
- 批处理:减少网络通信开销
- 利用操作系统
page cache来缓存数据:减少磁盘IO开销 - 零拷贝技术:减少数据多次拷贝开销
- 磁盘顺序写:减少寻道移臂开销
1. Kafka 的批处理
批量处理是一种非常有效的提升系统吞吐量的方法,减少网络通信开销。
在 Kafka 的客户端 SDK(软件开发工具包)中,Kafka 的 Producer 只提供了单条发送的 send() 方法,并没有提供任何批量发送的接口。
原因是,Kafka 根本就没有提供单条发送的功能,采用了异步批量发送的机制。
- 当你调用
send()方法发送一条消息之后 - 无论你是同步发送还是异步发送,
Kafka都不会立即就把这条消息发送出去 - 它会先把这条消息,存放在内存中缓存起来,然后选择合适的时机把缓存中的所有消息组成一批,一次性发给
Broker
各端批量处理数据:
- 生产端
Producer:内部批量发送。 - 消费端
Consumer:Consumer从Broker拉到一批消息后,在客户端把批消息解开,再一条一条交给用户代码处理。 Broker端:每批消息都会被当做一个“批消息”来处理。
2. Kafka 写入数据:page cache + 磁盘顺序写
通俗地说,
PageCache就是操作系统在内存中给磁盘上的文件建立的缓存。
-
应用程序在写入文件的时候,操作系统会先把数据写入到内存中的
PageCache,然后再一批地写到磁盘上。 -
读取文件的时候,也是从
PageCache中来读取数据,这时候会出现两种可能情况:-
PageCache中有数据,那就直接读取,这样就节省了从磁盘上读取数据的时间 -
PageCache中没有数据,这时候操作系统会引发一个缺页中断
应用程序的读取线程会被阻塞,操作系统把数据从文件中复制到
PageCache中,然后应用程序再从PageCache中继续把数据读出来,这时会真正读一次磁盘上的文件,这个读的过程就会比较慢。 -
流程如下:
- 接收到一批数据,
Kafka Broker直接写入Page Cache(Page Cache是基于OS Cache) Page Cache再顺序写入磁盘
3. Kafka 高效数据读取:零拷贝技术
当不使用零拷贝技术读取数据时:
流程如下:
-
消费端
Consumer:向Kafka Broker请求拉取消息 -
Kafka Broker从OS Cache读取消息到 应用程序的内存空间:- 若
OS Cache中有消息,则直接读取 - 若
OS Cache中无消息,则从磁盘里读取
- 若
-
再通过网卡,
socket将数据发送给 消费端Consumer
当使用零拷贝技术读取数据:
Kafka 使用零拷贝技术可以把这个复制次数减少一次,直接从 PageCache 中把数据复制到 Socket 缓冲区中。
- 这样不用将数据复制到用户内存空间。
DMA控制器直接完成数据复制,不需要CPU参与,速度更快。
零拷贝对应的系统调用:
#include <sys/socket.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);