当前位置: 首页 > news >正文

Kafka 分层存储(Tiered Storage)原理、配置、快速上手与生产落地

一、为什么需要分层存储?

在大多数业务场景中,Kafka 的消费是尾部读取(tail reads):新写入的数据直接命中 OS 页缓存(page cache),极少访问磁盘;只有在回补(backfill)故障恢复时,才偶尔回读很久以前的历史数据。
因此,把热数据留在 broker 本地磁盘,把冷数据(已完成的日志段)转移到廉价的远程存储(如 HDFS、S3)可以显著降低成本,同时保留回放能力,这就是 Tiered Storage 的核心价值。

二、工作机制一图观(简述)

  • Local(本地层):与传统 Kafka 相同,活跃段(active segment)仍在本地滚动写入。

  • Remote(远程层):当一个段滚动完成后,被上传到远程存储系统;随后,本地副本可根据 local.retention.* 策略删除

  • 读取路径

    • 尾部消费 → 命中页缓存或本地活跃段
    • 回放早期数据 → 按需从远程拉取段并提供给客户端(对消费者透明)

规范与背景可参考 KIP-405(分层存储提案)。

三、关键组件与配置项

1)Broker 级总开关

  • remote.log.storage.system.enable(默认 false):
    设为 true 才会在 broker 层启用分层存储功能。

2)远程段生命周期:RemoteStorageManager(RSM)

  • 职责:管理远程日志段与索引的生命周期(上传、下载、删除等)。

  • 注意:Kafka 不提供开箱即用实现,你必须配置:

    • remote.log.storage.manager.class.name
    • remote.log.storage.manager.class.path

教学/本地演示可使用官方集成测试实现 LocalTieredStorage(下文快速上手示例包含)。

3)远程段元数据:RemoteLogMetadataManager(RLMM)

  • 职责:以强一致语义维护远程段的元数据(位于何处、生命周期状态等)。

  • 默认实现:使用一个 Kafka 内部主题来存储元数据;如需替换,可设置:

    • remote.log.metadata.manager.class.name
    • remote.log.metadata.manager.class.path
  • 使用默认实现时必填

    • remote.log.metadata.manager.listener.name(指定 RLMM 内部客户端与 broker 通信使用的 listener 名称)

4)Topic 级别的开关与保留策略

  • remote.storage.enable(默认 false):开启该主题的分层存储。

  • 两组保留配置(启用分层存储后务必确认):

    • 时间:local.retention.msretention.ms
    • 大小:local.retention.bytesretention.bytes
  • 语义:local.* 用于控制本地日志副本的保留阈值(在已成功上传远程后方可删除);如未设置 local.*,将沿用 retention.* 的值。

四、快速上手:用 LocalTieredStorage 本地预演

目的:不接入 HDFS/S3,也能在本地验证分层存储的行为与指标。

1)构建测试库

# 在构建前切到你使用的版本 tag,例如:
git checkout 4.1.0./gradlew clean :storage:testJar
# 生成的测试 Jar 位于 storage/build/libs/kafka-storage-4.1.0-test.jar(文件名以实际版本为准)

2)Broker 示例配置(KRaft 模式,PLAINTEXT://:9092)

# 开启分层存储能力(broker 级)
remote.log.storage.system.enable=true# RLMM 默认实现的客户端要用哪个 listener 与 broker 通信
remote.log.metadata.manager.listener.name=PLAINTEXT# 指定 RSM 实现(此项为分层存储的刚需)
remote.log.storage.manager.class.name=org.apache.kafka.server.log.remote.storage.LocalTieredStorage
remote.log.storage.manager.class.path=/PATH/TO/kafka-storage-4.1.0-test.jar# 以下前缀为默认值,可自定义
remote.log.storage.manager.impl.prefix=rsm.config.
remote.log.metadata.manager.impl.prefix=rlmm.config.# LocalTieredStorage 的“远程目录”(确保 broker 有权限)
rsm.config.dir=/tmp/kafka-remote-storage# 多 broker 时需要合理设置副本因子
rlmm.config.remote.log.metadata.topic.replication.factor=1# 为观察效果,缩短保留检查周期
log.retention.check.interval.ms=1000

3)创建启用分层存储的主题

bin/kafka-topics.sh --create --topic tieredTopic --bootstrap-server localhost:9092 \--config remote.storage.enable=true \--config local.retention.ms=1000 \--config retention.ms=3600000 \--config segment.bytes=1048576 \--config file.delete.delay.ms=1000

含义速读:

  • remote.storage.enable=true:该 topic 使用分层存储
  • local.retention.ms=1000:段上传远程后,本地最多保留 1s(仅测试用)
  • retention.ms=3600000:远程段保留 1h
  • segment.bytes=1MiB:加速滚段,便于观察
  • file.delete.delay.ms=1000:加快本地删除延迟(测试用)

4)写入触发滚段

bin/kafka-producer-perf-test.sh \--topic tieredTopic --num-records 1200 --record-size 1024 \--throughput -1 --producer-props bootstrap.servers=localhost:9092

5)验证远程目录出现“冷段”

ls /tmp/kafka-remote-storage/kafka-tiered-storage/tieredTopic-0-<random-dir-id>
# 可见 .log / .index / .timeindex / .leader_epoch_checkpoint / .snapshot 等文件

6)从起始位置消费,确认 offset=0 可读(远程回放)

bin/kafka-console-consumer.sh \--topic tieredTopic --from-beginning --max-messages 1 \--bootstrap-server localhost:9092 --property print.offset=true

五、如何安全地“停用/冻结”分层存储(KRaft)

场景 A:让远程日志变为只读(停止继续拷贝)

  • 需求:历史远程段保留,但不再从本地复制新段到远程。

  • 设置:

    • remote.storage.enable=true
    • remote.log.copy.disable=true
    • 并将 local.retention.ms / local.retention.bytes 设置为与 retention.ms / retention.bytes 相同,或设为 -2(表示不再应用本地保留策略)
    • 原因:禁用远程复制后,本地保留策略将不生效,若不对齐可能导致本地磁盘写满
bin/kafka-configs.sh --bootstrap-server localhost:9092 \--alter --entity-type topics --entity-name tieredTopic \--add-config 'remote.storage.enable=true,remote.log.copy.disable=true,local.retention.ms=-2,local.retention.bytes=-2'

场景 B:彻底禁用并删除所有远程日志

  • 需求:不再使用分层存储,且清理该主题的远程段。

  • 设置:

    • remote.storage.enable=false
    • remote.log.delete.on.disable=true
bin/kafka-configs.sh --bootstrap-server localhost:9092 \--alter --entity-type topics --entity-name tieredTopic \--add-config 'remote.storage.enable=false,remote.log.delete.on.disable=true'

重要提示:集群级禁用的前置条件

若要在broker 层关闭分层存储(remote.log.storage.system.enable=false),必须先删除所有启用了分层存储的主题,否则 broker 启动会抛异常

bin/kafka-topics.sh --delete --topic tieredTopic --bootstrap-server localhost:9092
# 删除完所有相关主题后,再修改 broker 配置关闭系统级开关

六、局限与已知限制

  • 不支持 compacted 主题
  • 先按主题禁用:在 broker 层禁用分层存储之前,必须逐一在所有启用的 topic 上禁用。
  • 分层存储相关的管理操作仅在 3.0+ 客户端上受支持。
  • 不支持缺失 producer snapshot 文件的日志段(常见于v2.8.0 之前创建的主题)。
  • 一次 Fetch 请求仅可服务一个分区(当来自远程存储时):这可能限制消费者吞吐,可适当调大 max.partition.fetch.bytes
  • 更多细节可参考 Tiered Storage 的 GA Release Notes

七、生产落地建议与最佳实践

  1. 选型与实现

    • RSM 是关键:选择与你的对象存储/HDFS 生态匹配、吞吐稳定、具备重试与一致性保障的实现。
    • 元数据(RLMM)默认用内部主题即可;跨集群/跨域场景再考虑替换。
  2. 保留策略设计

    • segment.bytes 控制滚段频率,平衡上传开销与延迟。

    • local.retention.*retention.* 分层明确:

      • local.* → 控本地磁盘占用(仅限“已上传远程”的段
      • retention.* → 控远程历史保留(生命周期与合规要求)
    • 从“极致低成本”与“回放时延”之间找平衡。

  3. 容量与成本

    • 本地磁盘:按 local.* 预留足够空间,确保滚段与上传窗口不被突发流量击穿。
    • 远程存储:关注小对象放大效应(对象存储最小计费单元)、清理滞后与生命周期策略(Lifecycle)。
  4. 可观测性与告警

    • 关键指标:上传/下载失败率、远程读延迟、段回放命中率、RLMM lag、对象存储 4xx/5xx。
    • 告警阈值:远程拉取超时、max.partition.fetch.bytes 命中频度、磁盘水位、本地段滞留时间异常等。
  5. 兼容性与灰度

    • 客户端需 3.0+ 才支持全部管理操作。
    • 老主题(<2.8.0)可能存在 producer snapshot 缺失问题,建议新建主题迁移数据或完成一次“补快照”的重建流程。

八、运维清单(拿去即用)

启用前检查

  • 明确 RSM 实现与依赖(凭证、网络、带宽、限速策略)
  • 评审 local.retention.*retention.* 策略
  • 设定 segment.bytesfile.delete.delay.mslog.retention.check.interval.ms
  • 客户端版本 ≥ 3.0

上线步骤

  1. Broker 级开启:remote.log.storage.system.enable=true
  2. 配置 RSM/RLMM 相关项(尤其 remote.log.metadata.manager.listener.name
  3. 选定主题灰度开启:remote.storage.enable=true + 合理的 local.*/retention.*
  4. 写入/滚段/验证远程目录与回放(从 offset=0 消费)

日常运维

  • 监控上传/下载错误与延迟
  • 观察远程读带宽与账单
  • 定期核对远程 Lifecycle 与实际数据保留策略一致性

下线(禁用)

  1. 逐主题执行:

    • 只读冻结:remote.log.copy.disable=true + 对齐 local.* = retention.* 或设 -2
    • 彻底禁用并删除远程:remote.storage.enable=false, remote.log.delete.on.disable=true
  2. 删除所有启用过分层存储的主题

  3. Broker 级关闭:remote.log.storage.system.enable=false

九、常见问题(FAQ)

Q1:分层存储与 compacted 主题能否共用?
A:不支持 compacted 主题。需要压缩日志的场景暂不适合启用 Tiered Storage。

Q2:回放吞吐上不去怎么办?
A:远程读取时一个 fetch 只能服务一个分区,可能成为瓶颈。可适当调大 max.partition.fetch.bytes,并并发多分区消费。

Q3:为什么我禁用 broker 级开关后 Kafka 起不来?
A:必须禁用/删除所有启用了分层存储的主题,再关闭 broker 级开关;否则启动会报错。

Q4:老主题(2.8.0 之前创建)的段为何无法纳入远程?
A:这些段可能缺少 producer snapshot 文件。建议新建主题迁移或重建以补齐快照。

结语

分层存储把 Kafka 的“热写热读”与“冷数据回放”彻底解耦:
留本地、上云(或 HDFS),在成本、可靠性与回放能力之间找到最佳平衡。
按照本文的配置要点 → 快速上手 → 冻结/禁用策略 → 生产最佳实践一步步落地,你就能在保障稳定性的同时,有序地把 Kafka 存储成本打下来。祝上线顺利!

http://www.dtcms.com/a/393433.html

相关文章:

  • 多元函数微分学核心概念辨析:连续、偏导与可微
  • 9.21 快选|倍增|栈+贡献法
  • AI.工作助手.工作提效率.AI应用开发平台
  • 【名人简历】鲁迅
  • linux文件系统基本管理
  • 2.1 进程与线程 (答案见原书 P57)
  • SDL2 开发详解
  • c++ 深拷贝之 std::string 与 char*
  • [数理逻辑] 决定性公理与勒贝格可测性(II) 一维情况
  • [Tongyi] DeepResearch Model | MODEL_PATH
  • 儿童对话玩具模型设计与实现
  • 生成器迁移的偏差消除条件
  • LeetCode 刷题【86. 分隔链表】
  • 回溯.专题
  • QML学习笔记(五)QML新手入门其三:使用Row和Colunm进行简单布局
  • 【视图功能11】视图权限控制与协作场景实践
  • YOLOv5至YOLOv12升级:交通标志识别系统的设计与实现(完整代码+界面+数据集项目)
  • 双指针算法案例:有序顺序表的交并差
  • syn和quote实现派生宏Builder
  • MQTT消息质量等级——QoS
  • 【OpenGL】shader 着色器
  • 给AI装上“眼睛”:Schema标记和技术性GEO实战部署
  • 中超-克雷桑破门 齐鲁德比泰山2-2遭海牛读秒绝平!
  • gitflow在公司的全流程
  • 如何解决 pip install 安装报错 ModuleNotFoundError: No module named ‘grpc’ 问题
  • C语言第17讲
  • 人机协同开发中的“深水炸弹”——指令上下文混淆
  • 朴素贝叶斯算法详解:原理、应用与实践
  • 强化学习的数学原理-02章 贝尔曼公式
  • C++:入门基础(2)