4. 生产级硬件与操作系统选型

Kafka 的高可用并不只由副本机制决定,底层硬件与操作系统若选型不当,会让 ISR 频繁收缩、请求延迟抖动、Controller 频繁切换。本节从服务器规格、存储介质、文件系统、JVM、内核参数到网络配置,给出一条可落地的生产级选型与调优路径。

一、服务器规格:先定角色,再定配置

Kafka 集群中不同角色的资源画像差异明显,切忌所有节点“一刀切”。Broker 是 I/O 与网络密集型,Controller(KRaft 模式下)是元数据与选举敏感型,ZooKeeper(若仍使用)是低延迟小数据量型。

角色CPU内存存储网卡
Broker(高吞吐)16~32 核64~128 GBNVMe 数据盘 × 多块双口 10/25 GbE
Broker(低延迟)24 核以上128 GBNVMe,独立日志盘25 GbE
KRaft Controller8~16 核32~64 GB企业级 SSD10 GbE
ZooKeeper4~8 核16~32 GBSSD(事务日志独立)10 GbE

内存分配要区分“堆内”与“页缓存”。Kafka 严重依赖操作系统页缓存来加速日志段读取,因此堆内存不宜过大,通常 6~12 GB 即可,剩余内存留给页缓存。经验比例:堆内存不超过物理内存的 1/4,页缓存至少占 1/2。

二、存储类型:SSD 与 NVMe 的取舍

Kafka 的顺序写特性让机械盘也能跑,但生产环境必须用 SSD/NVMe,原因在于:副本追赶、分区重平衡、消费者滞后追赶都会产生大量随机读,机械盘的随机 IOPS 会直接拖垮 ISR 同步。

  • SATA/SAS SSD:约 5~10 万 IOPS,适合中小规模或日志保留期短的集群。
  • NVMe SSD:50 万~100 万 IOPS,延迟低至几十微秒,适合高吞吐、低延迟、大分区数场景。
  • RAID 策略:推荐 JBOD(每块盘独立挂载,Kafka 自带副本冗余),而非 RAID 5/6。RAID 卡写缓存反而增加写放大与故障域。
多块数据盘时,用 log.dirs=/data1,/data2,/data3,/data4 让 Kafka 把不同分区分散到各盘,避免单盘成为热点。

三、文件系统与挂载参数

推荐 XFS,其次 ext4。XFS 在大文件顺序写、并发元数据操作上更稳定。挂载时关闭 atime,减少不必要的元数据写入:

# /etc/fstab 示例
/dev/nvme0n1p1  /data1  xfs  defaults,noatime,nodiratime,logbufs=8,logbsize=256k  0 0

同时调整预读值,Kafka 顺序读场景下适当增大预读可提升吞吐:

blockdev --setra 4096 /dev/nvme0n1p1

四、JVM 调优:G1 为主,堆外要留足

Kafka 2.8 之后默认 G1 GC。生产建议固定堆大小,避免动态扩缩带来的停顿:

KAFKA_HEAP_OPTS="-Xms8g -Xmx8g"
KAFKA_JVM_PERFORMANCE_OPTS="-XX:+UseG1GC -XX:MaxGCPauseMillis=20 \
  -XX:InitiatingHeapOccupancyPercent=35 -XX:G1HeapRegionSize=16M \
  -XX:MetaspaceSize=96m -XX:+ExplicitGCInvokesConcurrent"

关键点:MaxGCPauseMillis=20 控制单次停顿;InitiatingHeapOccupancyPercent=35 提前触发并发标记,避免 Full GC;ExplicitGCInvokesConcurrent 让 System.gc() 走并发而非 STW。堆外内存(页缓存、DirectByteBuffer)要预留,容器环境下务必设置 -XX:MaxDirectMemorySize 与 cgroup 限制一致。

五、内核参数与网络配置

Kafka 高并发连接对文件描述符、网络缓冲区、TCP 行为敏感。以下为生产常用基线:

# /etc/sysctl.d/99-kafka.conf
vm.swappiness=1
vm.dirty_ratio=80
vm.dirty_background_ratio=5
net.core.somaxconn=32768
net.ipv4.tcp_max_syn_backlog=16384
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=4096 87380 16777216
net.ipv4.tcp_wmem=4096 65536 16777216
net.ipv4.tcp_window_scaling=1
net.ipv4.tcp_slow_start_after_idle=0

文件描述符与进程数限制:

# /etc/security/limits.d/kafka.conf
kafka  soft  nofile  1000000
kafka  hard  nofile  1000000
kafka  soft  nproc   65536
kafka  hard  nproc   65536

网络层面,Broker 间复制流量与客户端流量建议物理或 VLAN 隔离;num.network.threads 与 num.io.threads 按核数调整,通常网络线程为核数的 1/2,I/O 线程为核数的 1~2 倍。MTU 若交换机支持,可启用 Jumbo Frame(9000)降低大包复制开销。

生产级 Kafka 节点选型与调优全景 服务器规格 Broker: 16~32C / 64~128G Controller: 8~16C / 32~64G 堆内存 ≤ 物理内存 1/4 页缓存 ≥ 物理内存 1/2 双口 10/25 GbE 网卡 存储类型 NVMe SSD 优先 50万~100万 IOPS JBOD 多盘分散 log.dirs 多目录 避免 RAID 5/6 文件系统 XFS(推荐) noatime,nodiratime logbufs=8 预读 setra 4096 ext4 作为备选 JVM 调优 G1 GC -Xms = -Xmx = 8g MaxGCPauseMillis=20 IHOP=35 堆外内存预留 内核参数(sysctl) vm.swappiness=1 vm.dirty_ratio=80 / dirty_background_ratio=5 net.core.somaxconn=32768 tcp_rmem / tcp_wmem 16MB 上限 网络与资源限制 复制流量与客户端流量 VLAN 隔离 num.network.threads ≈ 核数/2 num.io.threads ≈ 核数×1~2 nofile=1000000 / nproc=65536 目标状态 ISR 稳定 · P99 延迟可控 · GC 停顿 < 20ms · 无 Swap · 副本追赶迅速 硬件选型 → 存储/文件系统 → JVM → 内核/网络,逐层消除瓶颈

六、落地检查清单

部署前逐项核对,可避免绝大多数“配置正确但性能不达标”的问题:

  1. 确认 log.dirs 指向多块 NVMe,且每块盘独立挂载、XFS、noatime。
  2. 确认 JVM 堆固定、G1 参数生效,jstat -gcutil 观察 Full GC 次数为 0。
  3. 确认 vm.swappiness=1,free -m 中 swap 使用为 0。
  4. 确认 ulimit -n 为 1000000,Broker 启动日志无 “Too many open files”。
  5. 确认网卡双口 bond 或独立 VLAN,ethtool -S 无丢包、无重传。
  6. 压测验证:用 kafka-producer-perf-test 与 kafka-consumer-perf-test 观察吞吐与 P99,确认 ISR 不收缩。
不要在生产环境使用 vm.dirty_ratio=80 却不监控脏页回写。若单盘写入突增,脏页堆积可能引发长时间 I/O 阻塞。建议配合 dirty_background_ratio=5 提前回写,并用 sar -d 或 iostat -x 1 持续观察 %util 与 await。

硬件与操作系统选型不是一次性工作。集群规模、分区数、保留策略变化后,应重新评估页缓存比例、I/O 线程数与网络队列。把上述参数纳入配置管理,配合监控告警,才能让 Kafka 的高可用真正落在生产环境里。