我想知道在.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()方法之前,这是有意义的。
我现在很好奇的是这两种选择都发生在内部。选择一个选项比另一个选项有什么优点/缺点吗?
答案 0 :(得分:3)
是的,有一个区别和不同的权衡:
1)使用through()
的第一个版本将创建一个“线性计划”,并将拓扑分为两个子拓扑。请注意,through("topic")
与to("topic")
加builder.stream("topic")
完全一样。
mainStream -> grp -> agg -> toStream -> to -> TOPIC -> builder.stream -> subStream
第一个子拓扑将从mainStream
到to()
; "aggregate-topic"
将其与由builder.stream()
组成的第二子拓扑分开,并馈入subStream
。这意味着,因为所有数据都首先写入"aggregate-topic"
,然后再读回。这将增加端到端处理延迟,并增加其他读取操作的代理负载。优点是两个子拓扑都可以独立并行化。它们的并行性是独立的,并由其相应的输入主题分区的数量确定。这将创建更多任务,从而允许更多的并行性,因为两个子拓扑都可以在不同的线程上执行。
2)第二个版本将创建一个“分支计划”,并将作为一个子拓扑执行:
mainStream -> grp -> agg -> toStream -+-> to -> TOPIC
|
+ -> subStream
在toStream()
之后,逻辑上将数据广播到两个下游运算符中。这意味着"aggregate-topic"
之间没有往返,但是记录将在内存中转发到subStream
。这减少了端到端延迟,并且不需要从Kafka集群读回数据。但是,您可以减少任务,从而减少最大并行度。