我们正在尝试实施以下所述的用例,我们遇到了需要克服的实现问题,
用例,
我们试图通过匹配两个流的messages(JSON)中存在的KEY,在2个Kafka主题之间进行KStream连接。 此外,当消息从源到达KStream时,我们还应保持消息序列。
场景是, 如果匹配密钥尚未到达流中的任何一个,我们应该停止或重试连接,直到期望的密钥到达其他主题。 我们曾考虑将不匹配的记录放回KStream,但在这种情况下不能保证顺序。
问题1: 如何停止或保持连接,直到其他主题中的期望键到达为止。 例如,KTable拥有密钥100,但是KStream尚未收到密钥100,那么我们应该重试Join或按住KStream直到密钥100到达。
问题2: 有什么方法可以将“延迟”或“间隔”放入KStream(“延迟的KStream”)中,以接收具有延迟时间或间隔的消息。
另外,我们必须从非键主题构建键KStream(键将通过从Message-JSON中提取键来设置)
最好使用Java,因为我们完成了POC以便在KTable和KStream之间进行联接
KTable<String, String> leftStream = builder.table("stream1");
KStream<String, String> rightStream = builder.stream("stream2");
KStream<String, String> outstream = rightStream.leftJoin(leftStream, (orig_msg, description) -> {
String new_msg = "";
if (description != null) {
new_msg = orig_msg+"-->Matched--"+description;
}else {
new_msg = orig_msg+"-->UnMatched<--"+description;
}
return new_msg;
});
答案 0 :(得分:0)
在示例中,您正在执行KStream-to-KTable LEFT连接。 Kafka Streams join semantics指定:(a)仅到达KStream的数据将触发联接输出,以及(b)如果在新的KStream事件到达时KTable中没有匹配的数据(联接的右侧),那么仍然会立即产生一个联接输出,但是对于表端数据使用null
(即,不会等待数据到达KTable端)。
问题1:如何停止或保持联接,直到其他主题中的期望键到达为止。例如,KTable拥有密钥100,但是KStream尚未收到密钥100,那么我们应该重试Join或按住KStream直到密钥100到达。
首先,您无法使用内置的Kafka Streams功能停止或保持联接。
第二,您提供的特定示例实际上不会发生,因为(参见上文)到达KTable的事件将不产生连接输出。仅当事件到达KStream时,才会与(a)的结果无关地(a)对KTable进行查找,并且(b)产生联接输出。
但是在KStream-KTable LEFT连接中可能发生的是相反的示例:KStream具有密钥100,但是KTable尚未接收密钥100。如何处理呢?见下文。
问题2:是否可以将“延迟”或“间隔”放入KStream(“延迟的KStream”)中,以接收具有延迟时间或间隔的消息。
是的,有很多方法可以做到这一点。但不适用于Kafka Streams DSL中的现有联接操作。
相反,您可以使用Kafka Streams的Processor API通过几行代码来实现所需的连接语义,然后将此功能插入DSL以方便重用。
有一个示例应用程序恰好演示了这一点,就像上面的用例一样:请参见https://github.com/confluentinc/kafka-streams-examples的CustomStreamTableJoin
(对于Confluent v5.2.1 / Apache Kafka 2.2,请参见direct link to CustomStreamTableJoin example )。
答案 1 :(得分:0)
谢谢Micheal,当我尝试上述Stream Example时,出现了以下问题,并且KStream立即关闭...(我创建的所有主题都具有单个分区)。 此外,我还必须深入研究KStream内部:-)。
stream-client [custom-join-integration-test-4af19e3b-8773-4e75-814e-56ea37839a59]状态从REBALANCING转换为PENDING_SHUTDOWN(org.apache.kafka.streams.KafkaStreams)