Kafka日志写入挂起根因是物理磁盘IO饱和,需从设备层反向定位真实IO路径:先用iostat -x 1综合%util、await、avgqu-sz判断是否真饱和,再用pidstat -d 1锁定高写进程,结合lsof和/proc/PID/io定位热点.log文件,最后排查Kafka配置、云盘配额、文件系统atime等协同性问题。

直接结论:Kafka 日志写入挂起不是 Kafka 自身故障,而是物理磁盘 IO 已饱和,必须从设备层反向定位到具体写入源——不能只查 Kafka 进程,要查它背后的真实 IO 路径。
iostat -x 1 看清是不是真“满”,别被 %util 带偏
很多人看到 %util = 100% 就断定磁盘打满,但 NVMe 盘或高队列深度场景下,%util 高可能只是请求短、并发密;而真正卡住业务的是 await 和 avgqu-sz。必须三者合看:
- 如果
%util高 +awaitavgqu-sz log.flush.interval.messages 设太小)或副本同步压测导致的瞬时写放大 - 如果
%util高 +await> 50ms +avgqu-sz> 8 → 物理 IO 确实拥堵,进入下一步排查 - 特别注意
r_await和w_await分离:Kafka 写挂起时,w_await通常远高于r_await,说明问题在写路径
pidstat -d 1 锁定真实写盘进程,警惕“伪 Kafka 进程”
pidstat -d 1 能暴露实际产生写 IO 的进程,但要注意 Kafka Broker 进程(如 kafka-server-start.sh)本身不直接写磁盘,真正落盘的是它的 JVM 线程(如 LogFlusher、LogCleaner),而这些线程在 pidstat 中会归到 JVM 进程名下,PID 不变。所以重点看:
- 哪个 PID 的
kB_wr/s持续 > 50MB/s?记下该 PID - 用
ps -p PID -o comm=确认是否为 Kafka JVM 进程(如java) - 用
cat /proc/PID/cmdline | tr '\0' '\n' | grep kafka验证是否 Kafka 启动命令 - 警惕同主机其他进程:比如日志采集 agent(
filebeat、fluentd)正在 tail 大量 Kafka 日志文件,也会触发相同路径的写放大
lsof + /proc/PID/io 定位到具体日志分段文件
Kafka 的写 IO 最终落在 .log 文件上,但一个分区下有多个 LogSegment,必须确认是哪个文件在高频写入:
- 先用
lsof -p PID | grep '\.log$'找出 Kafka 进程打开的所有.log文件路径 - 再查每个文件的写频次:
cat /proc/PID/io | grep write_bytes—— 注意这不是实时值,是累计值,需间隔几秒两次采样做差 - 结合 Kafka 目录结构判断热点:例如
/data/kafka-logs/order-topic-0/00000000000000123456.log写量突增,说明该 LogSegment 正在接收新消息,且可能因log.segment.bytes设置过大或消息体过大,导致单个.log文件长期不滚动,持续写入同一文件引发局部 IO 热点 - 若发现大量
.log文件同时被写(如多个分区都处于活跃写状态),说明是整体吞吐过高,而非单点异常
检查 Kafka 配置与磁盘后端协同性,特别是云环境
很多“IO 打满”其实是配置和硬件不匹配的结果,尤其在云盘场景下:
-
log.flush.scheduler.interval.ms和log.flush.interval.messages如果设得太小(如 1000/1),会导致频繁fsync,把随机小写放大成大量同步 IO,在云盘(尤其是 gp3/gp2)上极易触发限流,表现为await骤升但带宽未跑满 - 云盘 IOPS/吞吐配额是否被其他实例共享?比如 AWS EBS 同一宿主机上的邻居实例突发写入,会拖慢你的 Kafka 实例——此时本机
iostat看不到异常进程,但控制台能看到后端 IO 等待 - 检查磁盘是否启用了
barrier或cache=none:Kafka 推荐关闭页缓存(log.flush.offset.checkpoint.interval.ms配合page cache bypass),但如果底层存储不支持 direct IO,反而会因内核重试造成 IO 延迟累积 - SSD 寿命告警或坏块重映射也会表现为持续高
await和低%util,此时smartctl -a /dev/sdX可能显示Reallocated_Sector_Ct异常
最易被忽略的一点:Kafka 日志目录所在文件系统是否开启了 atime 更新?哪怕只是读取 .index 文件,也会触发元数据写入。在高吞吐场景下,这个看似微小的副作用会让 ext4 的 journal 写入量翻倍。临时禁用:mount -o remount,noatime /data,观察 IO 是否回落。











