乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • 学习路径
  • 第1章 消息队列与 Kafka 概述

    • 章节导读
    • 消息队列基础
    • Kafka 概述
    • Kafka 为什么快
  • 第2章 快速上手:单机环境搭建

    • 章节导读
    • 环境准备与安装
    • 快速启动
    • Topic 管理
  • 第3章 核心概念:主题、分区与日志

    • 章节导读
    • Topic
    • Partition
    • Offset
    • Segment 与存储结构
  • 第4章 生产者详解

    • 章节导读
    • Producer 概述
    • Producer 发送机制
    • Producer 分区策略
    • Producer 幂等与事务
    • Producer 配置
  • 第5章 消费者与消费组

    • 章节导读
    • Consumer 概述
    • Consumer Group 消费组
    • Consumer 分区分配策略
    • Consumer Offset 提交
    • Consumer 多线程
    • Consumer 配置
  • 第6章 Broker 与控制器

    • 章节导读
    • Broker 概述
    • Broker 配置
    • Controller
    • KRaft 共识协议
  • 第7章 副本与数据可靠性

    • 章节导读
    • 副本机制
    • ISR 与副本同步
    • Leader 选举
    • ACK 与一致性保证
    • 高水位与 Leader Epoch
  • 第8章 存储与性能优化

    • 章节导读
    • 存储架构
    • 日志清理与压缩
    • Page Cache 与零拷贝
    • Producer 性能优化
    • Consumer 性能优化
    • Broker 性能优化
  • 第9章 生产环境运维与监控

    • 章节导读
    • Topic 管理
    • Kafka 运维工具
    • 监控
    • 常见故障排查
  • 第10章 Kafka生态与面试考点

    • 章节导读
    • Kafka 生态全景
    • 面试高频 30 题

日志清理与压缩

定义与作用

Kafka 的数据不是无限增长的。日志清理(Log Cleanup)机制负责删除过期数据,释放磁盘空间。Kafka 提供两种清理策略:基于时间的删除(Delete) 和 基于 Key 的压缩(Compact)。

  • Delete:适合"流式数据"——超过保留时间后整条丢弃
  • Compact:适合"状态数据"——只保留每个 Key 的最新值

核心原理

Delete 策略

删除判断逻辑:

  1. 检查 Segment 文件中最后一条消息的时间戳
  2. 如果 now - maxTimestamp > retention.ms → 删除整个 Segment
  3. 活跃 Segment(当前正在写入的)永远不会被删除

Compact 策略

Compact 的特点:

  • 保留每个 Key 的最新值,删除旧值
  • 不影响 Consumer 的 Offset 消费(Consumer 按 Offset 读取,不会被压缩影响)
  • 适合保存"当前快照"(如用户配置表、最新交易状态)

清理线程架构

Log Cleaner 线程池:
  - 每个 log.dir 有 1 个清理线程
  - 周期扫描每个 Partition
  - Delete: 检查 Segment 时间戳 → 删除过期 Segment
  - Compact: 
    1. 选择"最脏"的 log(dirty ratio = 可清理消息数 / 总消息数)
    2. 清理旧 Key → 合并为新 Segment
    3. 替换旧 Segment

完整示例

示例一:配置基于时间的删除

# 创建保留 1 小时的数据流 Topic
bin/kafka-topics.sh --create --topic raw-events \
  --partitions 6 --replication-factor 3 \
  --config retention.ms=3600000 \
  --config segment.ms=600000 \
  --bootstrap-server localhost:9092

参数说明:

参数值含义
retention.ms3600000 (1小时)消息保留 1 小时
segment.ms600000 (10分钟)每 10 分钟切新 Segment

效果:每个 Segment 10 分钟。1 小时后,最早的那个 Segment 被删除。

示例二:配置 Log Compact 存储最新状态

# 创建 Compact Topic(保存用户最新登录信息)
bin/kafka-topics.sh --create --topic user-sessions \
  --partitions 3 --replication-factor 3 \
  --config cleanup.policy=compact \
  --config min.cleanable.dirty.ratio=0.5 \
  --config segment.ms=3600000 \
  --bootstrap-server localhost:9092

# 发送数据
bin/kafka-console-producer.sh --topic user-sessions \
  --property parse.key=true --property key.separator=: \
  --bootstrap-server localhost:9092
> user1:login-2026-06-01
> user2:login-2026-06-01
> user1:login-2026-06-13

操作前后对比:

Key初始状态(3 条消息)Compact 后Consumer 可见
user1v1, v3v3(保留最新)v1(如果 Offset 在那条), v3
user2v2v2(唯一值)v2

注意:Consumer 仍可读到被压缩的旧值(如果从那条 Offset 消费),Compact 只释放磁盘空间,不改变 Consumer 行为。

易错场景

易错 1:retention.bytes 设置为 -1(无限制)

场景:生产环境只配置了 retention.ms,没有配置 retention.bytes。

后果:如果写入速率极高,7 天的数据可能写满整个磁盘。

正确做法:始终设置 retention.bytes 作为磁盘保护:

retention.bytes=107374182400  # 100GB,即使时间未到也触发删除

易错 2:Compact Topic 不能保证"立即"回收

场景:期望 Compact Topic 中的数据实时反映最新值。

事实:Compact 是异步后台进程,不会在写入时立即压缩。消息可能在压缩前被 Consumer 消费到旧值。

规则:Compact 适用于最终一致性场景(如配置同步),不适合强一致性场景(如实时库存)。

面试高频考点

Q:Compact Topic 中,如果同一个 Key 写入 100 次,Consumer 从最早开始消费会看到多少条?

A:100 条。Compact 不影响 Consumer 的读取——Consumer 按 Offset 遍历所有消息。Compact 只删除标记为"已清理"的旧消息的磁盘副本,但这些消息对应的 Offset 仍然存在(以"墓碑"或直接跳过的方式)。

如果 Consumer 需要只看到每个 Key 的最新值,需要业务层去重或使用 KTable(Kafka Streams 提供)。

上一页
存储架构
下一页
Page Cache 与零拷贝