Apache kafka 卡夫卡流:按后续相同的键和时间窗口分组

Apache kafka 卡夫卡流:按后续相同的键和时间窗口分组,apache-kafka,kafka-consumer-api,apache-kafka-streams,Apache Kafka,Kafka Consumer Api,Apache Kafka Streams,我有一个可以这样描述的场景。想象有两种类型的钥匙进入:A和B(实际上,还有更多)。假设(不同)记录按以下顺序进入KStream: A1 A2 A3 B1 B2 A4 A5 在我的场景中,操作顺序很重要,我无法在B1或B2之前处理A4。但是,我希望能够批量处理记录。在我看来,批处理此输入的最佳选项如下所示,即将输入减少为3个“批处理”对象: 然后,我可以使用forEach对每个批次应用一个函数 复杂性:该应用程序对时间非常敏感,在其类型发生变化(需要新的批处理)之前,不允许保留聚合记

我有一个可以这样描述的场景。想象有两种类型的钥匙进入:A和B(实际上,还有更多)。假设(不同)记录按以下顺序进入KStream:

A1 
A2 
A3 
B1 
B2 
A4 
A5
在我的场景中,操作顺序很重要,我无法在
B1
B2
之前处理
A4
。但是,我希望能够批量处理记录。在我看来,批处理此输入的最佳选项如下所示,即将输入减少为3个“批处理”对象:

然后,我可以使用
forEach
对每个批次应用一个函数

复杂性:该应用程序对时间非常敏感,在其类型发生变化(需要新的批处理)之前,不允许保留聚合记录。换句话说,如果
A1
A2
之间的时间超过某个时间
t
,则当
t
到期时,应生成
A1
批次。然后输出如下所示(假设所有其他记录连续进入流):


问题:在考虑时间窗口的同时,如何获得具有此类批处理对象的KStream


我的初始解决方案(可能不起作用)用于最终场景(延迟在A1和A2之间):


这行吗?这有效吗?您的想法是什么?

您的要求非常具体,因此我认为DSL不适合您。我建议使用处理器API。用DSL本身实现这一点确实非常困难。我能够使用一个简化的场景来满足我的需求,只考虑了时间限制。但是,由于Kafka Streams仅在分区接受新记录时触发处理器(如中所述),因此通常不满足时间限制。e、 例如,当在某个时间点,两条记录同时进入时,包含这两条记录的批处理仅在新记录进入时(可能在数小时后)才会发布。您可以在处理器API中使用挂钟时间标点来解决此问题。
[A1 A2 A3]  
[B1 B2]  
[A4 A5]
[A1]
[A2 A3]  
[B1 B2]  
[A4 A5]
[KStream] incoming data with 2 possible keys: A or B, e.g. [ (A, A1), (A, A2), ...]
  |
  |   selectKey(key + something to separate A1, A2, A3 from A4 and A5 because B1 and B2 are inbetween) 
  v
[KStream] e.g. [ (A-group1, A1), (A-group1, A2), ... , (B-group2, B1), ..., (A-group3, A4) ]
  |
  |   groupBy(key)    // So either A-group1, B-group2 or A-group3
  v
[KGroupedStream] 3 different streams
  |
  |   WindowedBy  e.g. 1 second
  v
[TimeWindowedKStream] (still 3 different streams I guess?)
  |
  |   reduce()  --> Make "batch" objects out of window, e.g. a batch object is [A2, A3]
  v
[KTable]  (no idea how this look like, I guess one row per time window?)
  |
  |   toStream()
  v
[KStream] 1 stream with 4 entries like I described in the final scenario above