一、先搞清楚Kafka磁盘为什么不够用

Kafka就像个贪吃的小仓鼠,总喜欢把消息存在自己的小窝(磁盘)里。但这个小仓鼠有两个特点:一是特别能吃(高吞吐),二是不爱主动打扫(不会自动清理)。当磁盘快满时,通常有这些症状:

  1. 日志文件疯狂增长,每天能吃掉几十GB
  2. 消费者组滞后严重,出现"Lag飙升"警告
  3. 生产者开始报"NOT_ENOUGH_REPLICAS"错误

举个实际案例:某电商平台大促期间,订单消息突然暴增,第二天发现Kafka集群的/var/lib/kafka目录剩余空间不足5%。这时候我们需要双管齐下——既要快速腾出空间,又要规划长期解决方案。

二、紧急清理磁盘的三大妙招

2.1 调整日志保留策略

这是最立竿见影的方法,就像给仓库设置过期日期:

// 技术栈:Kafka Broker配置
# 修改config/server.properties
log.retention.hours=72       // 消息保留72小时(原先是168小时)
log.retention.bytes=1073741824  // 每个分区最多保留1GB(原先是无限制)

// 注意:动态生效需要执行
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name your_topic --alter --add-config retention.bytes=1073741824

2.2 手动删除陈旧日志

对于已经超期的"垃圾文件",可以直接动手清理:

# 技术栈:Linux Shell
# 找到超过7天的日志段文件
find /var/lib/kafka/data -name "*.log" -mtime +7 -exec ls -lh {} \;

# 安全删除(建议先ls确认)
find /var/lib/kafka/data -name "*.log" -mtime +7 -exec rm -f {} \;

2.3 巧用压缩主题

对于文本类消息,开启压缩能省出惊人空间:

// 技术栈:Kafka Producer
Properties props = new Properties();
props.put("compression.type", "gzip");  // 启用GZIP压缩
props.put("linger.ms", "100");          // 适当增加批处理时间
// 压缩率通常能达到4:1,但会略微增加CPU开销

三、长期扩容的四种姿势

3.1 纵向扩容:给磁盘"增高"

适合云环境,就像给服务器换个大硬盘:

# 技术栈:AWS CLI
# 检查当前EBS卷
aws ec2 describe-volumes --volume-ids vol-123456

# 扩容到500GB(需要先卸载)
aws ec2 modify-volume --volume-id vol-123456 --size 500

3.2 横向扩容:新增Broker节点

像给仓库增加新货架,操作分三步:

  1. 准备新服务器,安装相同版本的Kafka
  2. 修改所有Broker的server.properties
    num.partitions=6           # 建议分区数是Broker数的整数倍
    default.replication.factor=3 # 保持副本数一致
    
  3. 使用kafka-reassign-partitions.sh重新分配分区

3.3 冷热数据分离

把不常用的"老古董"移到廉价存储:

# 技术栈:Kafka Tiered Storage
# 在config/server.properties中添加
log.dirs=/fast_ssd/kafka,/slow_hdd/kafka  # SSD放新数据,HDD放旧数据

3.4 监控预警系统

装个"烟雾报警器",提前发现问题:

# 技术栈:Prometheus配置
alert_rules:
  - alert: KafkaDiskCritical
    expr: kafka_log_size_bytes / kafka_log_size_max_bytes > 0.8
    for: 15m
    labels:
      severity: critical
    annotations:
      summary: "Kafka磁盘空间不足 (instance {{ $labels.instance }})"

四、实战中的避坑指南

4.1 清理时的注意事项

  • 千万别直接删除正在写入的.log文件,会导致数据损坏
  • 修改保留时间后,Kafka不会立即删除文件,而是等待下一个日志段滚动
  • 建议在业务低峰期操作,避免影响生产消费

4.2 扩容时的隐藏陷阱

  • 分区重平衡期间性能下降约30%,最好分批操作
  • 跨可用区部署时,网络延迟可能影响副本同步
  • 新版Kafka(3.0+)支持增量扩容,老版本需要全量重启

4.3 特殊场景处理

遇到这些情况要特别小心:

  1. 消费者滞后严重时:先解决消费问题再清理,否则可能丢失消息
  2. 有事务消息时:确保transaction.state.log.min.isr配置合理
  3. 使用Connect或Streams:检查偏移量主题__consumer_offsets是否过大

五、最佳实践路线图

根据多年踩坑经验,我总结出这个操作优先级:

  1. 立即行动:调整保留策略 + 删除旧日志(治标)
  2. 中期规划:扩容存储 + 优化消息结构(治本)
  3. 长期建设:完善监控 + 制定容量规划(预防)

最后记住:Kafka磁盘管理就像打理花园——定期修剪(清理)很重要,但也要留出生长空间(扩容)。当你的集群日均消息量超过1TB时,建议考虑分层存储方案,把历史数据转移到S3这类对象存储中,这样既能保证性能,又控制成本。