Kafka Streams-使用through()与toStream()+ to()重用流

时间:2018-11-02 03:39:06

标签: apache-kafka apache-kafka-streams

我想知道在.toStream()+ .to()的流引用上使用.through()重用流的区别

使用.through()

KStream<String, String> subStream = mainStream .groupByKey(..) .aggregate(..) .toStream(..); .through("aggregate-topic", ..); // Then use the (new) stream from .through() to create another topic

与使用.toStream()+ .to()

KStream<String, String> subStream = mainStream .groupByKey(..) .aggregate(..) .toStream(..); subStream.to("aggregate-topic", ..); //reuse the existing subStream from toStream() to create another topic

我已经实现了使用后者的功能,因为在我学习through()方法之前,这是有意义的。

我现在很好奇的是这两种选择都发生在内部。选择一个选项比另一个选项有什么优点/缺点吗?

1 个答案:

答案 0 :(得分:3)

是的,有一个区别和不同的权衡:

1)使用through()的第一个版本将创建一个“线性计划”,并将拓扑分为两个子拓扑。请注意,through("topic")to("topic")builder.stream("topic")完全一样。

mainStream -> grp -> agg -> toStream -> to -> TOPIC -> builder.stream -> subStream

第一个子拓扑将从mainStreamto()"aggregate-topic"将其与由builder.stream()组成的第二子拓扑分开,并馈入subStream。这意味着,因为所有数据都首先写入"aggregate-topic",然后再读回。这将增加端到端处理延迟,并增加其他读取操作的代理负载。优点是两个子拓扑都可以独立并行化。它们的并行性是独立的,并由其相应的输入主题分区的数量确定。这将创建更多任务,从而允许更多的并行性,因为两个子拓扑都可以在不同的线程上执行。

2)第二个版本将创建一个“分支计划”,并将作为一个子拓扑执行:

mainStream -> grp -> agg -> toStream -+-> to -> TOPIC
                                      |
                                      + -> subStream

toStream()之后,逻辑上将数据广播到两个下游运算符中。这意味着"aggregate-topic"之间没有往返,但是记录将在内存中转发到subStream。这减少了端到端延迟,并且不需要从Kafka集群读回数据。但是,您可以减少任务,从而减少最大并行度。