问题描述
如综合文章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)
解决方法
Atm (Kafka 2.7.0) 行为如博客文章中所述。这个问题已经多次出现,我们最近创建了一张票来改变行为:https://issues.apache.org/jira/browse/KAFKA-10847
Atm,您可以在连接之后使用下游有状态操作来缓冲记录,直到达到窗口结束(或者可能更好,窗口关闭,即窗口结束加上宽限期)。这允许您过滤掉虚假的左/外连接结果。