Skip to content

存储与高吞吐

顺序写、页缓存、零拷贝、分区并行。

Updated View as Markdown
For humans

存储与高吞吐

Kafka 单机百万级吞吐的秘密:把随机 IO 变顺序 IO,把拷贝变零。面试必考四大机制。

四大机制

高吞吐四件套: 顺序写 + 页缓存 + 零拷贝 + 并行

1. 顺序写

  • 消息只追加到分区日志(log segment),不修改不随机
  • 磁盘顺序写速度接近内存(数百 MB/s),随机写只有几 MB/s
  • 对比:传统数据库随机写(B+树页更新)需要 redo 优化(见 WAL 篇)

2. 页缓存

  • 读写都走操作系统页缓存:写先落缓存(顺序写,刷盘由 OS),读命中缓存免磁盘
  • 消费不读磁盘:生产者写入的页还在缓存,消费者直接命中(生产消费同机时)
  • 对比:Kafka 不用自建缓存(JVM 堆),用 OS 页缓存(无 GC 压力、重启不丢)

3. 零拷贝

传统读取:磁盘 → 内核缓冲 → 用户缓冲 → 内核 socket → 网卡(4 次拷贝)

sendfile: 磁盘 → 页缓存 → 网卡(2 次, 用户态零参与)
  • sendfile 系统调用:数据从页缓存直达网卡,省去用户态拷贝
  • 消费场景的数据搬运成本近乎为零

4. 分区并行

  • 分区是并行单位:多分区 = 多日志文件 = 多磁盘 IO 队列
  • 吞吐随分区数线性增长(受限于单分区顺序写瓶颈)
  • 生产者/消费者都按分区并行

存储细节

概念 说明
log segment 日志分段文件(默认 1GB),旧段可删(保留策略)
保留策略 按时间/大小删除旧数据(不是消费后删)
稀疏索引 段内索引支持按 offset 定位(二分)
压缩 日志压缩(log compaction):只留每个 key 最新值

面试追问

  1. Kafka 为什么快? 顺序写 + 页缓存 + 零拷贝 + 分区并行。四件套
  2. 顺序写为什么快? 磁盘顺序 IO 接近内存速度(数百 MB/s),随机 IO 差两个量级
  3. 零拷贝是什么? sendfile:页缓存直达网卡,省用户态拷贝。消费近乎零成本
  4. Kafka 为什么不用自建缓存? OS 页缓存:无 GC 压力、进程重启缓存还在
  5. 消息什么时候删? 按保留策略(时间/大小),不是消费完就删。消费者可以重读
Navigation

Type to search…

↑↓ navigate↵ selectEsc close