Kafka是目前大型架构的核心中间件,也是大厂经常涉及的,下面我重点详解Kafka性能快的核心技术@mikechen
顺序写磁盘
Kafka 之所以能够实现高吞吐量,顺序写磁盘是其核心优化策略之一。
如下图所示:
Partition-0 ├── 00000000000000000000.log ├── 00000000000000000000.index ├── 00000000000000000000.timeindex ├── 00000000000000000100.log ├── ...
Kafka中每个主题分区对应一个日志文件(Log),消息以二进制形式顺序写入该文件。
并为每条消息分配唯一偏移量(offset),用于定位和顺序读取。
新的消息总是被追加到日志文件的末尾,就像写日志一样,只能在文件尾部添加新的记录。
顺序写入时,磁头只需要很少的移动,甚至可以认为是“步进式”地写入,避免了随机写入时大量的磁头移动,从而显著提升写入速度。
Page Cache
Kafka 写入消息时,并不是立刻将数据同步写入磁盘,而是先写入操作系统的 PageCache,再由操作系统异步刷盘。
这种设计实现了高吞吐 + 可持久化保障的完美平衡。
如下图所示:
Producer --> Kafka Broker(接收消息) --> 写入内存页缓存(PageCache) --> 刷写到磁盘文件(*.log)
Page Cache :是操作系统内核利用空闲的物理内存,来缓存最近访问过的磁盘数据。
当应用程序写入文件时,数据首先被写入到 Page Cache 中,这个过程是在内存中完成的,速度非常快。
为什么快?
因为写入内存(Page Cache),比直接写入磁盘要快得多。
KafkaProducer 将消息发送到 Broker,Broker 将消息追加到其分区日志文件的 Page Cache 中。
从而,无需等待磁盘 I/O 完成,从而实现了高吞吐量的写入。
零拷贝
当 Broker ,需要将消息发送给 Consumer 时,Kafka 利用操作系统的零拷贝技术(如 sendfile
)。
// Kafka 的 FileRecords 类中 channel.transferTo(position, count, targetChannel);
底层调用的就是 FileChannel.transferTo()
,而这在 Linux 上最终就是 sendfile
。
这允许数据直接从 Page Cache ,复制到网络套接字缓冲区,而无需经过 Kafka Broker 的用户空间。
磁盘 → 内核缓冲区 → 网卡 (中间不经过用户态,少两次拷贝)
从而,减少了数据拷贝的次数和上下文切换,显著提高了网络传输效率并降低了 CPU 开销。
批量发送
Kafka Producer 会将多个消息打包成一个批次进行发送,Consumer 也会批量地拉取消息。
这种批量处理的方式可以减少网络请求的次数,降低网络开销,并提高吞吐量。
mikechen
mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!

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