日志压缩主题不应与相同键保持重复。但是在我们的情况下,当发送具有相同键的新值时,不会删除前一个值。可能是什么问题?
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"}
答案 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)
分区的活动段永远不会被压缩,因此在开始删除较旧的重复项之前,可能需要一些时间并向主题发送更多消息。