4. 生产级硬件与操作系统选型
Kafka 的高可用并不只由副本机制决定,底层硬件与操作系统若选型不当,会让 ISR 频繁收缩、请求延迟抖动、Controller 频繁切换。本节从服务器规格、存储介质、文件系统、JVM、内核参数到网络配置,给出一条可落地的生产级选型与调优路径。
一、服务器规格:先定角色,再定配置
Kafka 集群中不同角色的资源画像差异明显,切忌所有节点“一刀切”。Broker 是 I/O 与网络密集型,Controller(KRaft 模式下)是元数据与选举敏感型,ZooKeeper(若仍使用)是低延迟小数据量型。
| 角色 | CPU | 内存 | 存储 | 网卡 |
|---|---|---|---|---|
| Broker(高吞吐) | 16~32 核 | 64~128 GB | NVMe 数据盘 × 多块 | 双口 10/25 GbE |
| Broker(低延迟) | 24 核以上 | 128 GB | NVMe,独立日志盘 | 25 GbE |
| KRaft Controller | 8~16 核 | 32~64 GB | 企业级 SSD | 10 GbE |
| ZooKeeper | 4~8 核 | 16~32 GB | SSD(事务日志独立) | 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)降低大包复制开销。
六、落地检查清单
部署前逐项核对,可避免绝大多数“配置正确但性能不达标”的问题:
- 确认
log.dirs指向多块 NVMe,且每块盘独立挂载、XFS、noatime。 - 确认 JVM 堆固定、G1 参数生效,
jstat -gcutil观察 Full GC 次数为 0。 - 确认
vm.swappiness=1,free -m中 swap 使用为 0。 - 确认
ulimit -n为 1000000,Broker 启动日志无 “Too many open files”。 - 确认网卡双口 bond 或独立 VLAN,
ethtool -S无丢包、无重传。 - 压测验证:用
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 的高可用真正落在生产环境里。