Apache kafka Kafka日志压缩始终显示同一密钥的最后两条记录

Apache kafka Kafka日志压缩始终显示同一密钥的最后两条记录,apache-kafka,Apache Kafka,发现了这两个问题:和,但我还是不太明白。 我仍然有(意想不到的?)行为 我尝试使用此配置记录compact kafka主题 kafka-topics.sh--引导服务器localhost:9092--创建--分区1--复制系数1--主题测试1--配置“cleanup.policy=compact”--配置“delete.retention.ms=1000”--配置“segment.ms=1000”--配置“min.cleanable.dirty.ratio=0.01”--配置“min.compr

发现了这两个问题:和,但我还是不太明白。 我仍然有(意想不到的?)行为

我尝试使用此配置记录compact kafka主题

kafka-topics.sh--引导服务器localhost:9092--创建--分区1--复制系数1--主题测试1--配置“cleanup.policy=compact”--配置“delete.retention.ms=1000”--配置“segment.ms=1000”--配置“min.cleanable.dirty.ratio=0.01”--配置“min.compression.lag.ms=500”

然后我发送这些消息,每个消息至少间隔1秒

A: 3
A: 4
A: 5
B: 10
B: 20
B: 30
B: 40
A: 6
我所期望的是在几秒钟后(配置为1000?),当我运行
kafka-console-consumer.sh--bootstrap server localhost:9092--property print.key=true--topic test1--从一开始
,我应该

A: 6
B: 40
相反,我得到了:

A: 5
B: 40
A: 6
如果我发布另一条消息
B:50
并运行consumer,我会得到:

B: 40
A: 6
B: 50
而非预期

A: 6
B: 50
  • 实际上,如何配置日志压缩
  • From:日志压缩确保Kafka在单个主题分区的数据日志中始终至少保留每个消息键的最后一个已知值
    这是否意味着我只能对单个分区的主题使用日志压缩

  • 基本上,你已经自己提供了答案。正如Kafka文档中所述,“日志压缩确保Kafka始终为单个主题分区的数据日志中的每个消息键保留至少最后一个已知的值”。因此,不能保证一个密钥始终只有一条消息

    如果我正确理解了日志压缩,那么它并不适用于您在非常有效的问题中提出的用例。相反,它意味着最终达到每个键只有一条消息出现在主题中的阶段

    日志压缩是一种机制,用于提供细粒度的每记录保留,而不是粗粒度的基于时间的保留。这样做的目的是有选择地删除记录,其中我们有一个使用相同主键的最新更新。这样可以保证日志中每个密钥至少有最后一个状态

    如果您计划只保留每个密钥的最新状态,以尽可能少地处理旧状态(非压缩主题的情况,取决于基于时间/大小的保留),则压缩主题是正确的选择。据我所知,日志压缩的用例是在数据库中保存最新地址、手机号码、值等。。不是每时每刻都在变化的值,通常有许多关键点

    从技术角度来看,我猜在你的案例中发生了以下情况

    当涉及到压缩时,日志被视为分成两部分

    • 清理:以前压缩过的邮件。本节仅包含每个关键点的一个值,即渗透压实时的最新值
    • 脏消息:上次压缩后写入的消息
    在生成消息
    B:40
    A:5
    已经生成)之后,日志的
    clean
    部分是空的,
    脏的/活动的
    部分包含
    A:5
    B:40
    。消息
    A:6
    根本不是日志的一部分。生成新消息
    A:6
    将开始压缩日志的脏部分(因为您的比率非常低),但不包括新消息本身。如前所述,没有什么需要清理的了,因此新消息将被添加到主题中,现在位于日志的脏部分。在生成
    B:50
    时,您所观察到的情况也是如此

    此外,压缩将不会在活动段上发生。因此,即使您将
    segment.ms
    设置为仅
    1000 ms
    ,它也不会生成新的段,因为在生成
    a:6
    B:50
    后没有新数据传入

    要解决您的问题并遵守期望,您需要在生成
    A:6
    B:50
    后生成另一条消息
    C:1
    。这样,清洁器可以再次比较原木的干净部分和脏部分,并将清除
    A:5
    B:40

    同时,看看这些片段在Kafka的日志目录中的行为


    从我的角度来看,日志压缩的配置非常好!它不是观察预期行为的正确用例。但是对于生产用例,请注意,您当前的配置尝试非常频繁地启动压缩。这可能会变得相当I/O密集,具体取决于数据量。默认比率设置为
    0.50
    ,log.roll.hours通常设置为24小时,这是有原因的。此外,您通常希望确保消费者有机会在数据压缩之前读取所有数据。

    您是如何生成消息的,以及使用什么配置?我想知道消息A:6和B:40的顺序是如何切换的(这应该与压缩无关)。这些消息通过调用Spring KafkaTemplate的API调用生成。除序列化器/反序列化器外,在生产者上没有配置。对不起,这是制作人顺序上的错别字