【问题标题】:Apache Flink EventTime processing not workingApache Flink EventTime 处理不起作用
【发布时间】:2021-01-29 00:42:24
【问题描述】:

我正在尝试在 KDA 上使用 Flink v1.11 应用程序执行流-流连接。加入 wrt 到 ProcessingTime 有效,但使用 EventTime 我看不到 Flink 的任何输出记录。

这是我的带有 EventTime 处理的代码,但它不起作用,

public static void main(String[] args) throws Exception {
    final StreamExecutionEnvironment env =
            StreamExecutionEnvironment.getExecutionEnvironment();
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    DataStream<Trade> input1 = createSourceFromInputStreamName1(env)
            .assignTimestampsAndWatermarks(
                    WatermarkStrategy.<Trade>forMonotonousTimestamps()
                            .withTimestampAssigner(((event, l) -> event.getEventTime()))
            );
    DataStream<Company> input2 = createSourceFromInputStreamName2(env)
            .assignTimestampsAndWatermarks(
                    WatermarkStrategy.<Company>forMonotonousTimestamps()
                            .withTimestampAssigner(((event, l) -> event.getEventTime()))
            );
    DataStream<String> joinedStream = input1.join(input2)
            .where(new TradeKeySelector())
            .equalTo(new CompanyKeySelector())
            .window(TumblingEventTimeWindows.of(Time.seconds(30)))
            .apply(new JoinFunction<Trade, Company, String>() {
                @Override
                public String join(Trade t, Company c) {
                    return t.getEventTime() + ", " + t.getTicker() + ", " + c.getName() + ", " + t.getPrice();
                }
            });
    joinedStream.addSink(createS3SinkFromStaticConfig());
    env.execute("Flink S3 Streaming Sink Job");
}

我有一个与 ProcessingTime 合作的类似加入

public static void main(String[] args) throws Exception {
    final StreamExecutionEnvironment env =
            StreamExecutionEnvironment.getExecutionEnvironment();
    env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);
    DataStream<Trade> input1 = createSourceFromInputStreamName1(env);
    DataStream<Company> input2 = createSourceFromInputStreamName2(env);
    DataStream<String> joinedStream = input1.join(input2)
            .where(new TradeKeySelector())
            .equalTo(new CompanyKeySelector())
            .window(TumblingProcessingTimeWindows.of(Time.milliseconds(10000)))
            .apply (new JoinFunction<Trade, Company, String> (){
                @Override
                public String join(Trade t, Company c) {
                    return t.getEventTime() + ", " + t.getTicker() + ", " + c.getName() + ", " + t.getPrice();
                }
            });
    joinedStream.addSink(createS3SinkFromStaticConfig());
    env.execute("Flink S3 Streaming Sink Job");
}

我尝试加入的两个流中的示例记录:

{'eventTime': 1611773705, 'ticker': 'TBV', 'price': 71.5}
{'eventTime': 1611773705, 'ticker': 'TBV', 'name': 'The Bavaria'}

【问题讨论】:

    标签: apache-flink flink-streaming amazon-kinesis-analytics


    【解决方案1】:

    我没有发现任何明显错误,但以下任何一项都可能导致此作业不产生任何输出:

    • 水印问题。例如,如果其中一个流变得空闲,则水印将停止前进。或者如果窗口之后没有事件,则水印将不会前进到足以关闭该窗口。或者,如果时间戳实际上不是按升序排列(使用 forMonotonousTimestamps 策略,事件应该按时间戳排序),管道可能会静默丢弃所有无序事件。
    • StreamingFileSink 仅在检查点期间最终确定其输出,并且在作业停止时不会最终确定任何待处理的文件。
    • 窗口连接的行为类似于内部连接,并且需要每个输入流中的至少一个事件才能在给定的窗口间隔内生成任何结果。从您分享的示例看来,这不是问题所在。

    更新:

    鉴于您(似乎)想要做的是将每个交易与交易时可用的最新公司记录连接起来,查找连接或临时表连接似乎是不错的方法。

    这里有几个例子:

    https://github.com/ververica/flink-sql-cookbook/blob/master/joins/04/04_lookup_joins.md

    https://github.com/ververica/flink-sql-cookbook/blob/master/joins/03/03_kafka_join.md

    一些文档:

    https://ci.apache.org/projects/flink/flink-docs-stable/dev/table/streaming/joins.html#event-time-temporal-join

    https://ci.apache.org/projects/flink/flink-docs-stable/dev/table/streaming/versioned_tables.html

    【讨论】:

    • 我不完全明白你提到的第二个问题可能是什么。由于 ProcessingTime 加入有效,我希望也能消除第三个问题。我认为这可能是一个水印问题,我仍然对此感到困惑。一旦我启动 Flink 应用程序,.currentInputWatermark 就是 -9223372036854776000(大约 Long.MIN_VALUE)。当我开始将事件提取到流中时,它移动到 1611929908(大约 3 小时前),而我的记录的时间戳为 1611939889(大约现在)。我正在使用 forBoundedOutOfOrderness(Duration.ofSeconds(10)) 策略。
    • 是的,我同意这很可能是水印问题。由于您共享的代码显示 forMonotonousTimestamps 而不是 forBoundedOutOfOrderness,因此我不确定我是否准确了解您的工作是如何处理水印的。
    • 我改回了描述中的确切代码,现在我看到了连接的输出!!!我看到 .currentInputWatermark 也接近事件时间。我相信相同的配置以前不起作用。我不再知道我在做什么:)
    • ci.apache.org/projects/flink/flink-docs-stable/learn-flink/… 上有一个关于水印的教程,您可能会觉得有帮助。
    • 非常感谢。我有一个用例,上面示例中的 Company 流是低容量流。假设公司名称每小时更改一次。交易流是每秒交易一次的大流量流。我想加入公司的所有行业。由于两个流的窗口大小相同,因此我不想在执行连接之前将 Trade 流状态保持一个小时,例如在滚动窗口中。
    猜你喜欢
    • 2017-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多