对 intervalJoin 感到困惑

时间:2021-03-25 15:40:07

标签: scala apache-flink flink-streaming

我正在尝试提出一种解决方案,该解决方案涉及在连接操作之后应用一些逻辑,以从多个 streamB 中的 EventB 中选择一个事件。它就像一个 reduce 函数,但它只返回 1 个元素,而不是增量执行。因此,最终结果将是单个 (EventA, EventB) 对,而不是 1 EventA 和多个 EventB 的叉积。

streamA
      .keyBy((a: EventA) => a.common_key)
      .intervalJoin(
          streamB
            .keyBy((b: EventB) => b.common_key)
        )
      .between(Time.days(-30), Time.days(0))
      .process(new MyJoinFunction)

数据将被摄取(假设它们具有相同的密钥):

EventB ts: 1616686386000

EventB ts: 1616686387000

EventB ts: 1616686388000

EventB ts: 1616686389000

EventA ts: 1616686390000

每个 EventA 密钥保证只到达一次。

假设有一个类似上面的连接操作,它生成了 1 个 EventA 和 4 个 EventB,在 MyJoinFunction 中成功连接和收集。现在我想要做的是,立即访问这些值并执行一些逻辑以将 EventA 正确匹配到 恰好一个 EventB。 例如,对于我需要的上述数据集 (EventA 1616686390000, EventB 1616686387000).

MyJoinFunction 将为每个 (EventA, EventB) 对调用,但我希望在此之后进行一个操作,它允许我访问迭代器,以便我可以查看所有 {每个 EventB 的 {1}} 个事件。

我知道我可以在加入后应用另一个窗口操作来对所有对进行分组,但我希望在加入成功后立即发生这种情况。因此,如果可能的话,我想避免添加另一个窗口,因为我的窗口已经很大(30 天)。

Flink 是这个用例的正确选择还是我完全错了?

1 个答案:

答案 0 :(得分:0)

这可以实现为 KeyedCoProcessFunction。您可以通过公共密钥对两个流进行加密,将它们连接起来,然后一起处理这两个流。

您可以使用 ListState 存储来自 B(对于给定键)的事件,并使用 ValueState 存储 A(同样对于给定键)。您可以使用事件时间计时器来了解何时到了查看 ListState 中的 B 事件并生成结果的时间。完成后不要忘记清除状态。

如果您不熟悉 Flink API 的这一部分,tutorial on Process Functions 应该会有所帮助。