连载中 13/20

Kafka 高吞吐的秘密:顺序写、零拷贝、批量压缩

2026-08-05 · 1001 阅读 · 0 评论 · 0 赞

一个总问题

同样是消息队列,为什么 Kafka 单机能跑到每秒百万条,而很多 MQ 只有几万条?答案不在某一个「黑科技」,而在三板斧的叠加:顺序写、零拷贝、批量压缩。这一篇把每一板斧的原理拆开看。

第一板斧:把随机写变成顺序写

先破除一个迷信:磁盘并不慢,慢的是随机寻道。机械硬盘随机写每秒只有几百次,但顺序写可以跑出每秒几百 MB——差距在百倍以上。SSD 上顺序写同样远快于随机写(写放大)。

Kafka 的存储设计全押在这上面:每个 partition 就是一个只追加的日志文件(日志段),新消息永远写在文件末尾,绝不修改中间数据。写入退化为最朴素的「append」,磁盘的好牌全打出来了。MySQL 系列讲过的 redo log 也是同样的哲学——把随机写变顺序写,是存储引擎的第一军规。

代价是查询麻烦:追加的文件怎么按 offset 找消息?Kafka 配了稀疏索引:不为每条消息建索引,每隔一段数据记一个 offset 到文件位置的映射(.index 与 .timeindex 文件,用 mmap 映射进内存)。先二分定位到附近的检查点,再顺序扫一小段——用一点点查找开销,换回纯追加的写入性能。

第二板斧:零拷贝,砍掉中间商

消费者来拉消息,数据要从磁盘走到网卡。传统路径是:

磁盘 --DMA--> 页缓存 --CPU--> 应用缓冲区 --CPU--> socket 缓冲区 --DMA--> 网卡
(4 次拷贝,应用进程只是个搬运工,数据在它手里过一下就走了)

Kafka 用操作系统提供的 sendfile 系统调用直接把中间两步砍掉:数据从页缓存直达网卡(零拷贝),CPU 一次都不碰数据,上下文切换也从四次减到两次。这个优化的前提恰恰是上一板斧——消息在文件里连续存放,才能整段整段地搬。叠加页缓存(Kafka 不自己管理缓存,热数据全靠操作系统的 page cache,进程重启缓存还在),消费者拉取命中缓存时,延迟低到接近内存操作。

第三板斧:批量与压缩,摊薄每一字节的路费

一百万条 100 字节的消息,逐条发是三次板斧都救不了的浪费:每条都要过一遍协议栈、记一次日志、做一次网络往返。Kafka 的生产端把消息攒批发送:攒够 batch.size(默认 16KB)或等满 linger.ms(默认 0,常调到 5-20ms),打包一起发。一批一万条消息,协议开销、磁盘写、网络往返全部摊薄一万倍。

攒起的批还能整体压缩(lz4、snappy、zstd、gzip)。文本类日志压缩比轻松到 5-10 倍,且 Kafka 支持端到端压缩:生产端压缩,Broker 原样落盘,消费者解压——全程不拆包,磁盘和网络一起省。代价是 linger.ms 带来的几毫秒延迟和 CPU 的压缩开销,吞吐型场景这笔账稳赚。

三板斧的成本账

技术收益代价/边界
顺序追加写写入快百倍不支持原地修改,删除靠整段过期
零拷贝CPU 空转减少,延迟降低依赖消息连续存储;SSL 加密场景失效
攒批压缩吞吐量级提升,带宽省数倍几毫秒攒批延迟;消耗 CPU

反过来指导业务

理解原理是为了用对姿势。三条落地建议:一是别往 Kafka 里塞大消息(图片、文件走对象存储,消息里只放 URL),大消息一破坏顺序写和零拷贝的前提,三板斧全废;二是吞吐优先的 Topic 才开攒批压缩,毫秒级敏感的业务把 linger.ms 设回 0;三是给 Broker 留足内存和页缓存,缓存命中率高,零拷贝才跑得欢。

小结

Kafka 的高吞吐没有魔法:顺序写把磁盘用对,零拷贝把 CPU 省下,批量压缩把路费摊薄。三者环环相扣,前提都是「消息按序连续存放」这个最朴素的设计决定。

性能说完了,下一篇说 Kafka 最让运维头疼的机制:分区与消费者组——Rebalance 风暴是怎么刮起来的,offset 的三种语义又该怎么选

503

10 年全栈工程师 · 503咖啡馆主理人

#消息队列#Kafka#顺序写#零拷贝#批量压缩

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞