未删除针对相同密钥的Kafka日志压缩主题重复值

时间:2020-04-10 13:02:32

标签: apache-kafka apache-kafka-streams apache-kafka-connect kafka-producer-api kafka-topic

日志压缩主题不应与相同键保持重复。但是在我们的情况下,当发送具有相同键的新值时,不会删除前一个值。可能是什么问题?

val TestCompactState: KTable[String, TestCompact] = builder.table[String, TestCompact](kafkaStreamConfigs.getString("testcompact-source"),
   (TestCompactmaterialized).withKeySerde(stringSerde).withValueSerde(TestCompactSerde)) 

我得到什么 实际结果

Offsets      Keys        Messages
5            {"id":5}   {"id":5,"namee":"omer","__deleted":"false"}
6            {"id":5}   {"id":5,"namee":"d","__deleted":"false"}

我只想针对同一把钥匙最新记录 预期结果

6            {"id":5}   {"id":5,"namee":"d","__deleted":"false"}

3 个答案:

答案 0 :(得分:4)

据我所知,不可能应用日志压缩策略来使每个密钥准确保持一条消息。即使您设置了cleanup.policy=compact(主题级别)或log.cleanup.policy=compact(全局级别),也不能保证仅保留最新消息,而压缩较旧的消息。

根据official Kafka documentation

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

答案 1 :(得分:3)

此行为可能有多种原因。压缩清理策略不会在每条传入消息之后运行。而是有broker configuration

log.cleaner.min.compaction.lag.ms :消息在日志中保持未压缩的最短时间。仅适用于正在压缩的日志。

类型:long;默认值:0有效值:;更新模式:集群范围内

此默认值为0,因此可能不是原因,但值得检查。

请务必注意,compact策略从不压缩当前段。消息仅适用于非活动段上的压缩。确保验证

log.segment.bytes :单个日志文件的最大大小

类型:int;默认值:1073741824;有效值:[14,...];更新模式:集群范围内

压缩通常将由日志的当前(“脏”)段中的数据触发。术语“脏污”来自未清理/未压缩的。还有另一种配置可以帮助控制压缩。

log.cleaner.min.cleanable.ratio :符合清除条件的日志的脏日志与总日志的最小比率。如果还指定了log.cleaner.max.compaction.lag.ms或log.cleaner.min.compaction.lag.ms配置,则日志压缩程序将在以下任一情况下立即认为该日志符合压缩条件:(i)已达到脏率阈值,并且日志至少在log.cleaner.min.compaction.lag.ms持续时间内具有脏(未压缩)记录,或者(ii)日志最多具有脏(未压缩)记录log.cleaner.max.compaction.lag.ms周期。

类型:双精度;默认值:0.5;有效值:;更新模式:群集范围

默认情况下,要压缩的邮件的删除滞后时间非常长,如以下配置说明所示。

log.cleaner.max.compaction.lag.ms :消息将保持不符合压缩条件的最长时间。仅适用于正在压缩的日志。

类型:long;默认值:9223372036854775807;有效值:;更新模式:集群范围内

总而言之,观察您所描述的内容可能有多个原因。有一个不错的blog,它详细说明了日志压缩。

答案 2 :(得分:0)

分区的活动段永远不会被压缩,因此在开始删除较旧的重复项之前,可能需要一些时间并向主题发送更多消息。