记录压缩以保持每个密钥只有一条消息

时间:2018-04-23 12:29:59

标签: apache-kafka

我想创建一个包含唯一键及其相应的最新值的主题。因此,当将具有现有密钥的消息插入到主题中时,将删除旧消息。

为此,我在server.properties文件中配置了以下参数:

log.cleaner.enable=true
log.cleanup.policy=compact

# The minimum age of a log file to be eligible for deletion due to age
log.retention.minutes=3

log.retention.bytes=10737418

# The maximum size of a log segment file. When this size is reached a new log segment will be created.
log.segment.bytes=1073741

# The interval at which log segments are checked to see if they can be deleted according
# to the retention policies
log.retention.check.interval.ms=60000

# The maximum time before a new log segment is rolled out (in milliseconds).
# If not set, the value in log.roll.hours is used
log.roll.ms=600000

因此压缩应每3分钟进行一次。为了测试压缩策略,我创建了一个主题retention_test

kafka-topics --zookeeper localhost:2181 --create --topic retention_test --replication-factor 1 --partitions 1

并使用控制台消费者kafka-console-producer --broker-list localhost:9092 --topic retention_test --property parse.key=true --property key.separator=:我已经生成了以下消息:

>1:first
>2:second
>3:third

控制台消费者kafka-console-consumer --bootstrap-server localhost:9092 --topic retention_test --from-beginning成功使用它们;

first
second
third

现在,当我尝试使用已添加的密钥插入消息时,旧消息似乎不会被忽略并保留在主题中:

在制片人方面:

>1:updatedFirst

请注意,为了测试行为,我在3分钟的保留期过去很久之后多次重新启动了使用者。输出是

first
second
third
updatedFirst

所需的输出应该是

second
third
updatedFirst

因为firstupdatedFirst具有相同的密钥。

根据docs

  

日志压缩为我们提供了更精细的保留机制,以确保我们保留每个至少上次更新   主键

是否可以为每个密钥保留完全一条消息(最近一条)而不是至少一条消息(包括最新消息)?

1 个答案:

答案 0 :(得分:2)

我说它一般不可能。 Kafka将消息分段存储为每个主题的每个分区。每个段都是一个文件,它们只被附加到(或作为一个整体删除)。压缩只能通过重写现有的段文件来跳过具有相同键的后续消息的消息。但是,头部分段(当前正在附加新消息的部分)不会被压缩(直到创建成为头部分段的新分段)。

log.retention时,您通过log.cleanup.policy=compact配置配置的3分钟无效,仅在log.cleanup.policy=delete

时有效

为什么只有一条给定密钥的消息很重要?如果您提供有关用例的更多信息,也许可以建议另一种方法。