开发者
鲲鹏服务器上 Kafka 磁盘 IO 利用率排查与优化
鲲鹏服务器上 Kafka 磁盘 IO 利用率排查与优化
原创
发表于05/07
160

问题描述

在鲲鹏 920 服务器(64 核 / 512GB 内存 / 2TB NVMe SSD)上部署 Kafka 3.6 集群做日志收集,发现 Broker 的磁盘 IO 利用率经常跑到 100%,但实际消息吞吐并不高。用 iostat -x 1 观察,NVMe SSD 的 %util 打满,await 飙到 20ms 以上,而 x86 同配置环境下 IO 利用率仅 30% 左右。

排查过程

# 查看当前 IO 调度器
cat /sys/block/nvme0n1/queue/scheduler

# 输出:
# [bfq] none mq-deadline kyber
# 当前使用 bfq 调度器

# 观察 IO 队列深度和等待时间
iostat -x 1 5

# 输出关键列:
# Device     r/s    w/s   await  %util
# nvme0n1   8500  12000   22.5  100.00
# await 22.5ms,%util 100%,IO 队列明显堆积

perf 分析 Kafka Broker 进程的 IO 相关系统调用:

perf record -e block:block_rq_issue,block:block_rq_complete -p $(pidof java) sleep 30
perf report --stdio

# 输出关键行:
#  12.3%  kworker/u96:0  [kernel]  [k] blk_mq_dispatch_rq_list
#   8.7%  kworker/u96:1  [kernel]  [k] bfq_dispatch_request
#   6.2%  java           [kernel]  [k] io_schedule

大量时间花在 bfq_dispatch_request 上。bfq(Budget Fair Queueing)调度器设计初衷是为 SATA HDD 优化顺序 IO,对 NVMe SSD 的高并发随机 IO 反而成为瓶颈——bfq 的合并排序逻辑增加了额外开销。

优化方案

第一步:切换 IO 调度器为 none

# NVMe SSD 有硬件多队列,不需要内核调度器做合并排序
echo none > /sys/block/nvme0n1/queue/scheduler

# 验证
cat /sys/block/nvme0n1/queue/scheduler
# 输出:[none] mq-deadline bfq kyber

# 永久生效(写入 udev 规则)
cat > /etc/udev/rules.d/60-nvme-scheduler.rules << 'EOF'
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/scheduler}="none"
EOF
udevadm control --reload-rules

第二步:优化 Kafka 刷盘配置

# server.properties
# 降低刷盘频率,让 OS 页缓存管理刷盘时机
log.flush.interval.messages=1000000
log.flush.interval.ms=60000

# 增大日志段最小大小,减少小段文件产生
log.segment.min.bytes=268435456   # 256MB

# 关闭 AOF 同步刷盘(如果开启了)
log.flush.offset.checkpoint.interval.ms=60000

第三步:NUMA 感知部署

# 查看磁盘所在 NUMA 节点
cat /sys/block/nvme0n1/device/numa_node
# 输出:0

# 将 Kafka Broker 绑到磁盘所在的 NUMA 节点
numactl --cpunodebind=0 --membind=0 \
  /opt/kafka/bin/kafka-server-start.sh /opt/kafka/config/server.properties

效果验证

使用 kafka-producer-perf-test 进行压测:

kafka-producer-perf-test --topic test \
  --num-records 10000000 \
  --record-size 1024 \
  --throughput -1 \
  --producer-props bootstrap.servers=localhost:9092
指标优化前(bfq)优化后(none)
IO 利用率100%35%
磁盘 await22.5ms0.8ms
消息吞吐85 MB/s240 MB/s
P99 生产延迟180ms12ms

小结

鲲鹏上 Kafka IO 利用率打满的根因是 bfq 调度器对 NVMe SSD 的高并发 IO 不适配,合并排序逻辑增加了额外开销。核心优化点:NVMe SSD 切换 none 调度器让请求直达硬件多队列、降低刷盘频率让 OS 管理缓存、Broker 按 NUMA 节点绑定。建议用 iostat -xperf record -e block:* 定位 IO 热点,确认调度器是否成为瓶颈。

收藏举报
Level 1
0
帖子
0
粉丝
0
获赞