如何合并多个kafka流,以便对结果流的所有事件进行会话窗口化

时间:2017-07-13 13:55:50

标签: apache-kafka apache-kafka-streams confluent

我们有多个输入主题,包含不同的业务事件(页面浏览量,点击次数,滚动事件等)。据我了解Kafka流,他们都获得了一个事件时间戳,可以用于与其他流或表的KStream连接以协调时间。

我们想要做的是:将所有不同的事件(源自上述不同主题)合并为用户ID(即按用户ID分组)并将会话窗口应用于它们。

这可以通过在包含所有事件的流上使用groupByKey然后aggregate/reduce(在此处指定非活动时间)来实现。此组合流必须按照事件时间的顺序包含来自不同输入主题的所有事件(或者以上述kafka流方法遵循此事件时间的方式)。

剩下的唯一挑战是创建这个合并/合并的流。

当我查看Kafka Streams API时,javadoc会执行KStreamBuilder#merge操作:There is no ordering guarantee for records from different {@link KStream}s.。这是否意味着会话窗口会产生不正确的结果?

如果是,#merge的替代方案是什么?

2 个答案:

答案 0 :(得分:3)

我也在考虑加入,但实际上它似乎取决于每个ID每个主题有一个事件,或者在一个输入主题中可能有多个具有相同ID的事件。对于第一种情况,加入是一个很好的策略,但不适用于后者,因为你会得到一些不必要的重复。

stream A: <a,1> <a,2>
stream B: <a,3>
join-output plus session: <a,1-3 + 2-3>

号码3将是重复的。

另外请记住,加入会略微修改时间戳,因此如果将它们应用于连接结果或原始数据,会话窗口可能会有所不同。

关于merge()并订购。您可以安全地使用merge(),因为将根据记录时间戳而不是偏移顺序构建会话窗口。 Kafka Streams中的所有窗口操作都可以优雅地处理无序数据。

答案 1 :(得分:0)

  

我们想要做的是:将所有不同的事件(源自上述不同的主题)合并为用户ID(即按用户ID分组)并将会话窗口应用于它们。

根据我的理解,您需要join the streams(并使用groupBy确保它们可以通过用户ID正确加入),而不是合并它们。然后,您可以使用会话窗口聚合进行跟进。