【问题标题】:kafka streams - joining partitioned topicskafka 流 - 加入分区主题
【发布时间】:2020-08-01 20:21:24
【问题描述】:

我的理解是 kafka 流支持分区。我想知道在加入来自两个不同主题的数据时它是如何工作的?我假设为了连接基于两个不同主题的数据,客户端应用程序必须确保它从两个主题获取的消息共享相同的密钥。只是想知道 kafka 流是如何做到这一点的?

【问题讨论】:

    标签: apache-kafka-streams


    【解决方案1】:

    有几个先决条件可以进行 stream-stream 、 ktable-ktable 或 stream-ktable 连接;

    • 主题需要共同划分。这意味着它们必须具有相同数量的分区。这个要求实际上是一个硬性要求,如果主题没有共同分区,流 API 将不允许加入,并且会在即将分配分区时在运行时抛出 TopologyBuilderException

    除此要求外,任何联接都可以正常工作,但要使其正常工作,还必须满足一些附加要求,例如;

    • 两个主题应该使用相同的键模式。例如,如果一个主题使用 userName 作为键,而其他 userSurname 加入操作将起作用,但很可能不会产生任何有意义的输出。
    • 写入连接主题的生产者应用程序应使用相同的分区策略。这样一来,相同的键最终会出现在分配给要加入的相同分区中。
    • 两个主题应该使用相同的消息时间戳策略(logAppendTime 或 CreateTime)。这不是每个人的要求,但如果主题使用不同的 messageTimeStampTypes,则应考虑用于窗口连接,因为 messageTimeStamps 用于确定要连接在一起的相关消息,如果缺少这一点可能会导致难以找到错误。

    GlobalKTable 连接没有任何此类要求,并且适用于每个主题,无论分区数、分区策略如何,因为 globalKTable 的所有数据都将呈现给每个单独的流实例。

    当消息产生时,它们将根据它们的键和分区策略发送到分区,流 API 将每个主题的相同主题分区分配给同一个处理器,以便来自具有相同键的同一主题的所有相关消息将在相同的处理处理器。对于窗口连接,消息时间戳被认为是为该特定窗口查找要连接的消息,并在连接完成后发出结果。

    【讨论】:

      【解决方案2】:

      其中一个难题是确保 Kafka 流为两个主题分配了相同的分区号。 为了保证这一点,它使用相同的消费者实例连接到两个主题,然后依赖范围分配器策略来获取相同的分区号。 见https://kafka.apache.org/24/javadoc/org/apache/kafka/clients/consumer/RangeAssignor.html

      【讨论】:

        猜你喜欢
        • 2016-10-15
        • 2019-10-11
        • 1970-01-01
        • 2016-10-01
        • 2015-03-05
        • 1970-01-01
        • 1970-01-01
        • 2020-05-01
        相关资源
        最近更新 更多