Apache kafka KStream到KTable内部联接,每次使用相同的数据处理时产生不同数量的记录

Apache kafka KStream到KTable内部联接,每次使用相同的数据处理时产生不同数量的记录,apache-kafka,apache-kafka-streams,spring-kafka,spring-kafka-test,Apache Kafka,Apache Kafka Streams,Spring Kafka,Spring Kafka Test,我想做一个KStream到KTable的连接。将KTable用作查找表。 下面的步骤显示了代码的执行顺序 构造KTable 可重调表 构建KStream 重新设置密钥流 加入KStream-KTable 假设KStream中有8000条记录,KTable中有14条记录,并假设KStream中的每个键在KTable中都有一条记录。因此,预期的输出将是8000条记录 每次我第一次加入或启动应用程序时。 预期的输出是8000条记录,但我有时只看到6200条记录,有时看到8000条完整的记录集(两次),

我想做一个KStream到KTable的连接。将KTable用作查找表。 下面的步骤显示了代码的执行顺序

  • 构造KTable

  • 可重调表

  • 构建KStream

  • 重新设置密钥流

  • 加入KStream-KTable

  • 假设KStream中有8000条记录,KTable中有14条记录,并假设KStream中的每个键在KTable中都有一条记录。因此,预期的输出将是8000条记录

    每次我第一次加入或启动应用程序时。 预期的输出是8000条记录,但我有时只看到6200条记录,有时看到8000条完整的记录集(两次),有时没有记录,等等

    • 问题1:为什么每次运行应用程序时记录都不一致

      在构造KTable(construct+Rekey)之前,先构造KStream,然后从KStream端连接数据,然后连接从out KTable开始,这样在构造KTable之前,在最终连接中不会看到数据。构造完KTable之后,我们可以看到其余记录的连接发生

    • 问题2:如何解决加入记录的不一致性

      我尝试使用嵌入式Kafka for KStream和Ktable join测试用例。有10条来自KStreams的记录和3条来自KTable的记录用于该过程。当我第一次运行测试用例时,没有连接,连接后我没有看到任何数据。第二次跑步时,它跑得非常完美。如果我清除状态存储,则返回零

    • 问题3:为什么会发生这种行为

      我尝试使用KSQL,连接工作得很好,我得到了8000条记录,然后我进入了KSQL源代码,我注意到KSQL也在执行相同的连接功能

    • 问题4:KSQL如何解决该问题

    我看到了一些示例建议的答案

    • 使用不起作用的GlobalKTable。我得到了同样的不一致的加入
    • 使用自定义细木工 这不管用
    我使用SpringCloudStreams作为依赖项

    我还看到在JIRA的某个地方有一个公开的问题

    下面的步骤显示了代码的执行顺序

    请注意,构建拓扑只是提供数据流程序的逻辑描述,没有不同运算符的“执行顺序”。程序将被翻译,所有操作员将同时执行。因此,来自所有主题的数据将并行读取

    这种并行处理是您观察的根本原因,即在处理开始之前没有首先加载表(至少默认情况下没有保证),因此即使表没有完全加载,也可能会处理流端数据

    不同主题之间的处理顺序取决于记录时间戳:首先处理时间戳较小的记录。因此,如果要确保首先处理KTable数据,则必须确保记录时间戳小于流侧记录时间戳。当您将输入数据生成到输入主题中时,或者通过使用自定义时间戳提取器,可以确保这一点

    其次,从主题获取数据是不确定的,因此,如果只返回流端数据(而不是表端数据),则无法进行时间戳比较,因此流端数据将在表端数据之前进行处理。要解决此问题,可以增加配置参数
    max.task.idle.ms
    (默认值为
    0ms
    )。如果您增加此配置(我相信KSQL在默认情况下也会这样做),如果一个输入没有数据,任务将阻塞并尝试获取空输入的数据(只有在空闲时间过后,即使一侧为空,处理也将继续)

    对于
    GlobalKTable
    来说,行为是不同的。此表将在启动时加载,然后再开始任何处理。因此,我不知道为什么这对你不起作用