Kafka log.segment.bytes 与 log.retention.hours

May*_*hav 10 apache-kafka retention kafka-topic kafka-partition

我正在阅读《Kafka:权威指南》第一版这本书来了解代理何时删除日志段。

根据我理解的文本,一个段在关闭之前不会被删除。仅当段达到 log.segment.bytes 大小时才能关闭(考虑未设置 log.segment.ms)。一旦某个段符合删除条件,log.retention.ms 策略将应用以最终决定何时删除该段。

然而,这似乎与我在生产集群(Kafka 2.5 版)中看到的行为相矛盾。

一旦满足 log.retention.ms,日志段就会被删除,即使段大小小于 log.segment.bytes。

[2020-12-24 15:51:17,808] INFO [日志分区=Topic-2,dir=/Folder/Kafka_data/kafka]由于保留时间604800000ms违规(kafka.log.日志)

[2020-12-24 15:51:17,808] INFO [日志分区=Topic-2, dir=/Folder/Kafka_data/kafka] 调度删除段 List(LogSegment(baseOffset=165828, size= 895454171 , lastModifiedTime=1608220234000,最大时间=1608220234478)) (kafka.log.Log)

大小仍然小于 1GB,但该段已被删除。

该书在新闻发布时提到 Kafka 版本是 0.9.0.1 。这个设置在 Kafka 的后续版本中也发生了变化。(我在 Kafka 文档中找不到任何具体提及此更改的信息)。以下是书中的片段。

在此输入图像描述

Mun*_*ish 22

设置:log.retention.mslog.retention.bytes

\n

Kafka Broker 保留消息的时间(实际上是 \xe2\x80\x9clog 段\xe2\x80\x9d)最常见的配置是按时间(以毫秒为单位),并使用log.retention.ms参数指定(默认为 1 周)。如果设置为 -1,则不应用时间限制。

\n

另一种过期方式是基于保留的消息的总字节数。该值是使用log.retention.bytes参数设置的,并且应用于每个分区。它的默认值为-1,允许无限保留。这意味着,如果您的主题有 8 个分区,并且 log.retention.bytes 设置为 1 GB,则该主题保留的数据量最多为 8 GB。如果您同时指定了log.retention.byteslog.retention.ms,则当满足任一条件时,消息可能会被删除。

\n

设置:log.segment.byteslog.segment.ms

\n

当消息生成到 Kafka 代理时,它们会被附加到分区的当前日志段中。一旦日志段达到log.segment.bytes参数指定的大小(默认 1 GB),日志段将被关闭并打开一个新的日志段。只有当日志段被关闭后,才可以考虑将其过期(通过log.retention.mslog.retention.bytes)。

\n

控制日志段何时关闭的另一种方法是使用参数log.segment.ms,该参数指定日志段应关闭的时间量。当达到大小限制或达到时间限制时(以先到者为准),Kafka 将关闭日志段。

\n

较小的日志段大小意味着必须更频繁地关闭和分配文件,这会降低磁盘写入的整体效率。如果主题的生成率较低,则调整日志段的大小可能很重要。例如,如果某个主题每天仅接收 100 MB 的消息,并且log.segment.bytes设置为默认值,则需要 10 天才能填满一个分段。由于消息在日志段关闭之前不会过期,因此如果log.retention.ms设置为 1 周,则实际上会保留最多 17 天的消息,直到关闭的段过期。这是因为,一旦使用当前 10 天的消息关闭日志段,根据时间策略,该日志段必须在过期前保留 7 天。

\n

  • 我不明白为什么这个答案得到这么多分,因为这只是“卡夫卡:权威指南”的复制粘贴。令我着迷的是,问题的作者投票认为这是最佳答案,尽管他引用了同一本书。我错过了什么吗? (2认同)

Kha*_*111 8

希望这变得更加清楚。

segment.ms => 段文件的最大年龄(从创建之日起)

Retention.ms => 分段(已关闭)中任何消息的最长期限,超过该期限该分段就有资格删除(如果设置了删除策略)

因此,如果该段是“活动段”,那么它可以根据segment.ms(或segment.bytes)滚动,但不能根据retention.ms滚动。保留仅在封闭(非活动)段上发挥作用。

所以书中引用的行为是正确的。但是,您认为该段处于活动状态,并且 INFO 日志指定该段已设置为删除。这不会发生在活动段上(假设没有错误)。该段必须先关闭(不活动),然后任何retention.* 属性才能生效。

看到这个

  • 这是一个有用的总结和线索@Khanna111 (3认同)