Apache kafka 阅读Kafka Streams DSL中的主题

Apache kafka 阅读Kafka Streams DSL中的主题,apache-kafka,apache-kafka-streams,Apache Kafka,Apache Kafka Streams,在卡夫卡流中重新划分一个高容量的主题可能非常昂贵。一种解决方案是在制作人一侧用一个键对主题进行分区,并在Streams应用程序中摄取一个已经分区的主题 有没有办法告诉Kafka Streams DSL我的源主题已经被给定的键分区了,不需要重新分区 让我澄清我的问题。假设我有这样一个简单的聚合(为了简洁起见,省略了细节): 给定此代码,Kafka Streams将读取消息主题,并立即将消息写回内部重新分区主题,这次由msg.field作为键进行分区 一种简单的方法是,首先编写由msg.field

在卡夫卡流中重新划分一个高容量的主题可能非常昂贵。一种解决方案是在制作人一侧用一个键对主题进行分区,并在Streams应用程序中摄取一个已经分区的主题

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


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

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

一种简单的方法是,首先编写由
msg.field
分区的原始
消息
主题。但是Kafka Streams对
消息
主题划分一无所知,我发现没有办法告诉它主题是如何划分的,而不会导致真正的重新划分

注意,我并没有试图完全消除分区步骤,因为必须对主题进行分区才能计算键控聚合。我只想将分区步骤从Kafka Streams应用程序向上游转移到原始主题生成器

我要找的基本上是这样的:

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

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

问题更新后更新:如果您的数据已经按需分区,您只需要聚合数据而不需要进行重新分区操作(对于您的用例,这两种操作都是正确的),那么您只需要使用
groupByKey()
而不是
groupBy()
。虽然
groupBy()
总是导致重新分区,但它的同级
groupByKey()
假定输入数据已经按照现有消息键按需要进行了分区。在您的示例中,如果
key==msg.field
,则
groupByKey()将起作用

下面的原始答案:

在卡夫卡流中重新划分一个高容量的主题可能非常昂贵

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

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

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

一种解决方案是在制作人一侧用一个键对主题进行分区,并在Streams应用程序中摄取一个已经分区的主题


考虑到你的这种变通方法,我的印象是你提问的动机是其他的(你必须有一个特定的想法),但你的问题文本没有明确说明这可能是什么。也许您需要更新问题的更多细节?

是的,问题是关于每秒处理数百万个事件的主题。我已经更新了我的问题,并试图更好地解释我试图实现的目标。谢谢更新我们的答案,鲍里斯。您是否检查了
groupByKey()
函数(而不是
groupBy()
,它总是会导致对输入数据进行重新分区)?它假设输入数据已经按照现有的消息键按需要进行了分区。在您的示例中,如果
key==msg.field
,则
groupByKey()
将起作用。我错过了最明显的解决方案。真可惜!不知何故,我认为
groupByKey
需要事先调用
selectKey
groupBy
来设置键。Wish文件明确指出,这是不必要的@迈克尔。诺尔我可以请你更新你的答案,这样我就可以把它标记为接受了吗?不用担心,很容易错过!我更新了我的答案。关于文档混乱:有没有关于如何改进的建议?今天说:“当且仅当流被标记为重新分区时,才会导致数据重新分区。groupByKey优于groupBy,因为它仅当流已经被标记为重新分区时才会重新分区数据。但是,groupByKey不允许您像groupBy那样修改密钥或密钥类型。”关于文档,这有意义吗?当且仅当流被标记为要重新分区时,才会导致数据重新分区。groupByKey比groupByKey更可取,因为它仅当流已被标记为要重新分区时才会重新分区数据,否则它会假定输入数据已按需按照现有消息键进行分区。如果您只想聚合在不进行重新分区操作的情况下删除数据,然后只需使用groupByKey()。但是,groupByKey不允许您像groupBy那样修改密钥或密钥类型。“@MichaelG.Noll
builder
    .stream("messages")
    .assumeGroupedBy((key, msg) -> msg.field)
    .count();