Apache Kafka Broker 磁盘有空间仍拒写:OfflineLogDirectoryCount 暴露的是目录故障 📅 发布时间:2026/9/11 18:17:25 👁 浏览次数: title: Apache Kafka 4.3.1 Broker 磁盘有空间仍拒写OfflineLogDirectoryCount 暴露的是目录故障date: 2026-08-30series: Apache Kafka 4.3.1 机制、面试与生产实践part: 生产故障复盘columns: [消息队列, 生产运维]tags: [Apache Kafka, Kafka 4.3.1, Log Directory, Retention, Tiered Storage]description: 从挂载点、离线日志目录、段级保留与分层存储解释“总磁盘有空间”的误判。target_version: Apache Kafka 4.3.1last_verified: 2026-08-31Apache Kafka 4.3.1 Broker 磁盘有空间仍拒写OfflineLogDirectoryCount 暴露的是目录故障主机监控显示还有 40% 空闲Producer 却连续超时部分分区无 Leader。值班同学看到的是根盘总量Kafka 失败的是另一个log.dirs挂载点Broker 进程仍活着日志目录已经被标记离线。Kafka 写入能力取决于承载目标分区的具体日志目录、文件系统与副本状态不取决于主机总磁盘的一张绿灯。五种“有空间但不能写”现象实际原因关键证据根盘空闲、数据盘满看错挂载点log.dirs与文件系统映射容量空闲、目录离线I/O、权限、只读文件系统OfflineLogDirectoryCount、Broker 日志单目录热点分区分布不均每目录分区大小保留已到期但未释放活跃段未滚动、段级删除延迟segment 与 retention 配置本地层满误以为远端存储会自动兜底tiered storage 开关与 local retentionKafka 的log.dirs是 Broker 只读启动配置可能包含多个目录。Broker Configs 任何一个目录故障都可能使其中副本离线而进程和其他目录仍正常。Retention 不是实时按字节删记录日志以 segment 为单位管理。retention.bytes是每个分区的限制不是整个 Topic需要乘分区数估算 Topic 规模。时间/大小条件使旧 segment 具备删除资格不代表一到阈值就逐条释放空间。Topic Configs Log Implementation如果当前活跃段很大、滚动周期长或者文件删除有延迟磁盘水位可能继续上升。Compact Topic 还遵循不同的清理语义不能按 Delete Topic 的速度估算。分层存储也有本地层Kafka 4.3.1 默认不启用 Tiered StorageBroker 侧需要配置远端实现Topic 还要显式remote.storage.enabletrue。启用后本地层仍保存数据并由local.retention.ms/bytes控制。Tiered Storage Tiered Storage Configs远端对象存在不等于本地磁盘可以忽略上传积压、元数据异常或本地保留配置不当都能造成压力。只读取证不要先删文件1. 查 Broker 实际目录配置bin/kafka-configs.sh --bootstrap-server broker:9092\--entity-type brokers --entity-name3--describe--all只读确认log.dirs再到对应主机按挂载点查看容量、inode、只读状态和 I/O 错误。不要只看/。2. 查副本落在哪个目录bin/kafka-log-dirs.sh --bootstrap-server broker:9092\--describe--broker-list3该命令只读可看到目录、TopicPartition、大小和错误。若只有单目录异常范围就不是整个 Broker。3. 查 Topic 保留与清理策略bin/kafka-configs.sh --bootstrap-server broker:9092\--entity-type topics --entity-name audit-events--describe核对cleanup.policy、retention.ms/bytes、segment.ms/bytes与远端存储配置。配置“正确”仍需结合分区数和实际 segment 年龄。4. 对齐指标OfflineLogDirectoryCount正常应为 0同时看OfflineReplicaCount、无 Leader 分区、ISR 变化、磁盘 I/O 与远端复制指标。Monitoring应急处置顺序限制非关键 Topic 写入保护关键业务和控制面。恢复故障挂载、权限或 I/O确认目录重新可用前不要盲目重启循环。若需要迁移副本先评估剩余磁盘和网络分批执行并观察 ISR。通过配置缩短保留只能删除符合策略的旧 segment不能保证立即腾出目标空间。绝不手工删除 Kafka 日志文件也不要用rm清目录这会破坏副本与日志元数据一致性。修改 retention、迁移副本或禁用远端存储都是高风险操作。必须保存原配置、精确到 Topic/分区、单批 canary以 ISR 稳定、写入恢复、磁盘水位下降为成功条件以副本离线增加、远端读取失败或业务校验异常为停止条件并恢复原配置或停止后续批次。长期预防按挂载点、目录和 Broker 三层监控容量与 inode。容量模型按分区和副本计算并预留副本迁移与故障恢复空间。对 segment 滚动、retention 资格与实际删除建立差异告警。Tiered Storage 同时监控本地保留、远端复制和元数据 Topic。定期演练单目录故障而不是只演练整个 Broker 停机。源码与 Java按 Broker 查看真实 LogDir而不是看根盘以下源码定位与 Java 示例按 Kafka 4.3.1 静态审阅未在本环境运行查询本身只读但输出的目录路径应按生产敏感信息处理。Admin 请求由KafkaAdminClient.describeLogDirs发出Broker 的目录故障通过LogDirFailureChannel传播日志目录与其中副本可独立离线。importjava.util.*;importorg.apache.kafka.clients.admin.*;publicclassLogDirProbe{publicstaticvoidmain(String[]args)throwsException{PropertiespnewProperties();p.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG,localhost:9092);try(AdminadminAdmin.create(p)){MapInteger,MapString,LogDirDescriptionalladmin.describeLogDirs(List.of(1,2,3)).allDescriptions().get();all.forEach((broker,dirs)-dirs.forEach((path,d)-System.out.printf(broker%d path%s error%s replicas%d%n,broker,path,d.error(),d.replicaInfos().size())));}}}error!null或预期目录缺失时转查对应挂载点和 Broker 日志。映射是 Admin API → Broker log dir state →LogDirFailureChannel→ offline replica/拒写。查询只读但目录名可能暴露部署信息它不能替代主机容量和 inode 检查。结论“磁盘有空间”必须回答哪台 Broker、哪个挂载点、哪个日志目录、哪个分区和哪一层存储。只有把目录健康、segment 生命周期、副本状态与 Producer 错误对齐才能避免用删除文件或随意改保留制造二次事故。