KStream连接立即触发连接功能,如何在窗口结束时延迟它?

问题描述

如综合文章Crossing the Streams中所述。外部KStream-KStream联接在到达时就立即发出元素,甚至在其他K-Stream中等待其匹配之前也是如此。这样做的缺点是它会复制未加入的事件以及每个加入的事件。

您能建议任何其他方法来实现事件的连接而不重复(如在外部连接中)或丢失(如在内部连接中)吗?


按照相同的点击查看事件示例

KStream<String,JsonNode> joinedEventsstream = 
     clickEventsstream.outerJoin(viewEventsstream,(clickEvent,viewEvent) -> processJoin(clickEvent,viewEvent),/* Fire quickly if match found,*/
                                                                          /* else fire after 2 seconds */
            JoinWindows.of(Duration.ofSeconds(2L)),StreamJoined.with(Serdes.String(),jsonSerde,jsonSerde)
    );

预期结果如下:

  • 点击事件在视图后1秒到达-已加入事件(A,A)
  • 点击事件在视图后11秒到达-每个事件都有不同的事件。到达后2秒(窗口大小)中的每一个(B,null)(null,B)
  • 观看事件在点击后1秒钟到达-加入的事件(C,C)
  • 一个观看事件,但没有点击-到达事件2秒后未加入的事件(D,null)
  • 有点击事件,但没有观看次数-到达事件2秒后未加入事件(null,E)

expected outer join

解决方法

Atm (Kafka 2.7.0) 行为如博客文章中所述。这个问题已经多次出现,我们最近创建了一张票来改变行为:https://issues.apache.org/jira/browse/KAFKA-10847

Atm,您可以在连接之后使用下游有状态操作来缓冲记录,直到达到窗口结束(或者可能更好,窗口关闭,即窗口结束加上宽限期)。这允许您过滤掉虚假的左/外连接结果。