GlobalWindows在Flink的同一个GlobalWindows中分配具有相同键的元素?

时间:2017-06-05 08:47:48

标签: apache-flink flink-streaming

基于下面的文档“全局窗口分配器将具有相同密钥的所有元素分配给同一个全局窗口”

https://ci.apache.org/projects/flink/flink-docs-release-1.2/dev/windows.html

然后我检查了源代码并发现GlobalWindows的assignWindows方法只返回全局Window并且没有为参数元素做任何事情,那么如何将所有具有相同键的元素放到同一个全局窗口中?

https://github.com/apache/flink/blob/12b4185c6c09101b64e12a84c33dc4d28f95cff9/flink-streaming-java/src/main/java/org/apache/flink/streaming/api/windowing/assigners/GlobalWindows.java

@Override
public Collection<GlobalWindow> assignWindows(Object element, long timestamp, WindowAssignerContext context) {
    return Collections.singletonList(GlobalWindow.get());
}

1 个答案:

答案 0 :(得分:2)

在Flink中,窗口和密钥在很大程度上是相互独立的。流元素可以按键和窗口分组,这些是正交维度。 (当我们想谈论窗口与密钥的组合时,这称为窗格。)

窗口实例没有键,窗口分配器也没有。相反,键和键分区状态是评估窗口的运行时上下文的一部分。

当我试图理解窗口分配器的密钥关系时,我发现阅读WindowOperator's implementation of processElement很有帮助。当每个流元素到达窗口运算符时,调用此代码。注意关键的作用,同时遗漏了很多其他细节,我们看到了这一点:

public void processElement(StreamRecord<IN> element) throws Exception {
    final Collection<W> elementWindows = windowAssigner.assignWindows(
        element.getValue(), element.getTimestamp(), windowAssignerContext);

    ...

    final K key = this.<K>getKeyedStateBackend().getCurrentKey();

    ...

    for (W window: elementWindows) {

        ...

        windowState.add(element.getValue());

        triggerContext.key = key;
        triggerContext.window = window;

        TriggerResult triggerResult = triggerContext.onElement(element);
        if (triggerResult.isFire()) {
            ...
            emitWindowContents(window, contents);
        }

        ...
    }
}

在这里,您可以看到窗口操作符可以通过getKeyedStateBackend()使用该键,但在从窗口分配器获取此元素的窗口之后,甚至无法检索该键。窗口分配器完成其工作而不用担心密钥。

稍后会获取该键,以便可以通过触发器上下文使其可用于触发器。