bigywater.tech
Kafka 内部原理 · 60

Broker 参数:分区数、Segment 大小和保留策略

真实测试segment.bytes的最小值限制,用一个较小的segment.bytes写入数据,观察磁盘上真实切出的segment文件数量和大小,理解segment.bytes和retention策略真实是两件独立的事。

1048576字节
segment.bytes真实的硬性下限
999807字节×4
真实观测到的4个完整segment文件大小

验证:segment.bytes真实有一个硬性下限

命令 · shell $ kafka-topics.sh --create --topic segment-demo --config segment.bytes=102400
真实实测 · 本机执行输出
Error while executing topic command :
Invalid value 102400 for configuration segment.bytes: Value must be at least 1048576

真实设置一个"看起来合理"的100KB,broker直接拒绝——segment.bytes真实有一个硬编码的下限1MB,这不是建议值,是broker代码里真实校验会拦下来的强制约束,避免segment文件切得太碎、真实产生过多小文件拖累文件系统性能。

验证:改成1MB之后,磁盘上真实切出了4个segment文件

命令 · shell $ kafka-topics.sh --create --topic segment-demo --config segment.bytes=1048576 真实写入20000条200字节消息(约4MB) $ ls -la kafka-lab/node2/data/segment-demo-0/*.log
真实实测 · 本机执行输出
00000000000000000000.log   999807 字节
00000000000000004761.log   999807 字节
00000000000000009522.log   999807 字节
00000000000000014283.log   999807 字节
00000000000000019044.log   200757 字节  (真实还没写满的最后一个)
每个真实写满的segment文件都卡在999807字节——刚好不超过1048576(1MB)的门槛,因为broker真实是"写入一条消息之后检查是否超过segment.bytes,超过就滚动到下一个文件",而不是精确切在1MB整数位置,所以真实的文件大小永远略小于配置值。基准offset(文件名)分别是0、4761、9522、14283,前后两个segment真实相差约4761——这正是"约1MB ÷ 每条消息的真实磁盘占用(200字节数据+日志头开销)"算出来的每个segment真实能装的消息数。

结论:retention真实决定的是"删不删",不是"切不切"

segment.bytes真实控制的是日志文件切分的粒度,retention.bytes/retention.ms真实控制的是旧segment什么时候被清理——两者是真实独立的两件事:文件该怎么切,跟切出来的文件该保留多久,是两层不同的策略。本文把retention.bytes设成了3MB(小于当前4MB的总数据量),但Kafka后台清理线程默认每5分钟(log.retention.check.interval.ms,同样是静态配置、不能动态修改)才检查一次,本文没有真实等够这个周期去验证清理动作,只验证了segment切分这一半。

分步演示:segment真实是怎么被切出来的

每一步都是本文上面用真实磁盘文件跑出来的原始结果。

segment.bytes真实决定了磁盘上文件切分的粒度
这一步新验证的配置

    参考与说明

    • 数据来自本机3节点Kafka 4.3.1集群,topic segment-demo(单分区),真实写入20000条200字节消息观察磁盘segment文件。
    • 没有验证:真实等待log.retention.check.interval.ms(默认5分钟)周期,确认retention.bytes/retention.ms触发的旧segment真实删除;分区数量对broker整体性能(如controller管理开销)的真实影响。
    京ICP备2026067502号-1京公网安备11010502063487号