繁体   English   中英

在 Kafka Streams DSL 中读取已经分区的主题

[英]Reading already partitioning topic in Kafka Streams DSL

在 Kafka Streams 中对大容量主题进行重新分区可能非常昂贵。 一种解决方案是通过生产者侧的键对主题进行分区,并在 Streams 应用程序中摄取已经分区的主题。

有没有办法告诉 Kafka Streams DSL 我的源主题已经被给定的键分区并且不需要重新分区?


让我澄清一下我的问题。 假设我有一个这样的简单聚合(为简洁起见,省略了详细信息):

builder
    .stream("messages")
    .groupBy((key, msg) -> msg.field)
    .count();

鉴于此代码,Kafka Streams 将读取messages主题并立即将消息写回内部重新分区主题,这次由msg.field作为键进行分区。

使这种往返变得不必要的一种简单方法是首先编写由msg.field分区的原始messages主题。 但是 Kafka Streams 对messages主题分区一无所知,我发现无法告诉它主题是如何分区的,而不会导致真正的重新分区。

请注意,我并不是要完全消除分区步骤,因为必须对主题进行分区才能计算键控聚合。 我只想将分区步骤从 Kafka Streams 应用程序上游转移到原始主题生产者。

我正在寻找的基本上是这样的:

builder
    .stream("messages")
    .assumeGroupedBy((key, msg) -> msg.field)
    .count();

其中,assetGroupedBy 会将assumeGroupedBy标记为msg.field分区。 我知道这个解决方案有点脆弱,并且会在分区键不匹配时中断,但它解决了处理大量数据时的问题之一。

更新问题后更新:如果您的数据已经根据需要进行了分区,并且您只想聚合数据而不需要重新分区操作(两者都适用于您的用例),那么您只需要使用groupByKey()而不是groupBy() 虽然groupBy()总是导致重新分区,但它的兄弟groupByKey()假设输入数据已经根据现有消息键的需要进行了分区。 在您的示例中,如果key == msg.fieldgroupByKey()将起作用。

原答案如下:

在 Kafka Streams 中对大容量主题进行重新分区可能非常昂贵。

是的,没错——它可能非常昂贵(例如,当高容量意味着每秒数百万个事件时)。

有没有办法告诉 Kafka Streams DSL 我的源主题已经被给定的键分区并且不需要重新分区?

除非您指示,否则 Kafka Streams 不会重新分区数据; 例如,使用KStream#groupBy() function。 因此,无需像您在问题中所说的那样告诉它“不要分区”。

一种解决方案是通过生产者侧的键对主题进行分区,并在 Streams 应用程序中摄取已经分区的主题。

鉴于您的这种解决方法,我的印象是您提出问题的动机是其他的(您必须考虑到特定的情况),但是您的问题文本并没有明确说明可能是什么。 也许您需要用更多细节更新您的问题?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM