Kafka流在groupby到stream提交后发送部分reduce输出后减少

时间:2018-09-26 09:50:08

标签: apache-kafka apache-kafka-streams

我们遇到一个问题,即在进行groupby-> reduce-> toStream时,如果在reduce期间发生提交,则会向下游发送部分reduce值。因此,如果有65个要减少的键,并且说一次提交发生在整个过程的一半,那么输出将是两条消息:一条消息部分减少,另一条消息所有值都减少。

这是我们的案例的详细信息:

msg --> leftJoin
leftJoin --> flatMap //break msg into parts so we can join again downstream
flatMap --> leftJoin
leftJoin --> groupByKey
groupByKey --> reduce
reduce --> toStream
toStream --> to

当前,我们为此提出了一个非常丑陋的解决方案,它与在flatMap阶段创建的每条消息中添加索引并从值中删除值有关...我们过滤掉reduce发出的任何消息其中索引!=超出。我的感觉是我们不是在这里做某事,也不是在错误地看待它。请提供正确的方法建议。

谢谢。

1 个答案:

答案 0 :(得分:1)

  

因此,如果要减少65个键,并且说一次提交发生在整个过程的一半,那么输出将是两条消息:一条消息部分减少,另一条消息所有值都减少。

如果我正确理解了您的描述,这实际上是预期的行为。一方面,这是处理延迟(您希望在拥有新的输入数据后立即查看更新记录)与将多个更新记录合并为更少甚至仅一个更新记录之间的权衡。

Kafka Streams的默认行为是在发送下游更新之前不等待“所有输入数据都已到达”。相反,一旦新数据到达,它将发送更新。 https://www.confluent.io/blog/watermarks-tables-event-time-dataflow-model/中描述了一些背景信息。

今天,您有两个主要旋钮可以更改/调整此默认行为,这由(1)Kafka Streams record caches (for the DSL)和(2)配置的提交间隔(您已经提到过)控制。

向前迈进,Kafka社区还一直在开发一项新功能,该功能将使您可以定义仅发送单个最终更新记录(而不是所谓的“部分”更新)。如果您有兴趣,可以在Kafka改进建议KIP-328: Ability to suppress updates for KTables中介绍此新功能。这项工作正在积极进行中,但不太可能在十月份即将推出的Kafka v2.1版本中及时完成。

  

当前,我们为此提出了一个非常丑陋的解决方案,它与在flatMap阶段创建的每条消息中添加索引并从值中删除值有关...我们过滤掉reduce发出的任何消息其中索引!=超出。我的感觉是我们不是在这里做某事,也不是在错误地看待它。请提供正确的方法建议。

简而言之,在流处理中,您应该接受流工作方式的本质。通常,您只能对世界有部分/不完全的了解,或者说:您只知道到目前为止所观察到的内容。因此,在任何给定的时间点,您都必须处理可能会收到更多仍需要处理的更多数据的情况。

一种典型的情况是必须处理迟到的数据,在这种情况下,应用程序逻辑必须决定是否仍然要集成和处理此数据(很有可能)还是丢弃(有时是需要的方式)。

回到您的示例:

  

因此,如果有65个要减少的键[...]

人们怎么会知道它是65,而不是100或28,依此类推?只能说:“到目前为止,我已经收到65。所以,我该怎么办?我会减少65,因为我相信这就是所有输入吗?或者我等待了几秒/分钟/小时,因为可能还要再等待35秒,但这是否意味着我不会在等待时间过去之后向下游发送更新/答案?”

在您的情况下,我想问:您为什么考虑如何/何时发送更新的流式传输问题?也许是因为您的下游系统或应用程序不知道如何处理此类流更新?

这有意义吗?同样,以上内容基于我对您所描述的问题的理解。