美文网首页
Flink_window窗口计算如何解决乱序,延迟,迟到数据问题

Flink_window窗口计算如何解决乱序,延迟,迟到数据问题

作者: Eqo | 来源:发表于2022-09-02 22:43 被阅读0次

Flink四大基石

window窗口 Time时间 Status状态 Checkpoint检查点

1.窗口Window和Time时间

image.png

Flinkwindow窗口,相当于把流式数据转换成一批次一批次,批处理
分类:

  • timewindow时间窗口
    根据时间划分窗口
  • countwindow数量窗口
    根据数量划分窗口
  • sessionwindow会话窗口
    根据会话间隔划分窗口

窗口根据窗口大小和窗口间隔分为滚动窗口,滑动窗口

  • 滚动窗口 窗口大小=窗口间隔
  • 滑动窗口 窗口大小>窗口间隔

窗口根据数据流分为
分组流窗口(常用)
数据流窗口


Time时间:
Flink 时间语义
1.11版本之前:

  • 事件时间EventTime,指的就是数据产生的数据,比如订单数据中订单时间

  • 摄入时间InjectionTime,指的就是数据被Data Source获取到时间

  • 处理时间ProcessingTime,指的就是数据被转换处理的时间

    1.11版本开始:
    事件时间EventTime 和 处理时间ProcessingTime


2.窗口计算

Flink流式计算当中最重要的就是 基于事件时间的时间窗口计算
EventTime事件时间的滚动窗口 ★★★★★
EventTime事件时间的滑动窗口 ★★★★
EventTime事件时间的会话窗口 ★★★★

  • 如果对窗口数据计算时,需要对窗口数据进行排序操作,肯定使用全局窗口数据计算
  • 普通窗口数据计算,通常属于窗口增量计算,调用算子:reduce、aggregate
  • 优化:先增后全方式窗口数据计算

3.基于事件时间窗口计算

  • step1.必须指定数据流中,事件时间的字段,且必须是long类型
  • step2.设置窗口聚合函数
    [对DataStream进行窗口计算时,通常情况下,都是先对数据流进行分组,再对分组流进行窗口计算】
    datastream.keyBy.window.apply/process/reduce/aggregate
    全量 apply process)(增量 reduce aggregate)

4.基于时间事件的窗口计算时,如何处理乱序,延迟和迟到数据

【一个原则:基于事件时间窗口计算,不要让数据丢失,可以单独侧边流输出,进行处理分析】
下述方案,针对滚动窗口和滑动窗口,与会话窗口没有关系
默认情况:触发窗口计算后,窗口销毁

方案一 Watermark水印

【时间方式,处理乱序数据】

  • 可以设置窗口数据触发计算时,等一等时间,再触发计算
  • 相当于给每条数据的事件时间加一个时间戳,
    列如窗口大小为5m,设置 Watermark为2m
    9.01-9.05 但是9.06也会被计算,
    9.06这条数据相当于 事件时间- Watermark水印时间
    会触发一次窗口计算.
方案二 Allowed Lateness 允许延迟

【空间方式,内存保存窗口计算结果,处理延迟数据】

  • 把窗口计算的结果,再在内存中保存一段时间,延迟数据到达时会再次触发窗口计算. Allowed Lateness不能设置时间太大,会造成性能浪费
  • 当窗口数据触发计算以后,如果有窗口数据达到,依然参与计算
方案三 Side Output 侧边输出

兜底操作,将以上两种方案没有处理后的乱序,延迟和迟到数据,作为侧边流输出,单独处理

5.乱序数据、延迟数据、迟到数据,如何界定?

    1. 乱序数据
      基于事件时间窗口计算时
      没有设置Watermark机制,数据不会被窗口计算;
      如果设置Watermark以后,数据将会被窗口计算;
      【此时这条数据就是乱序数据,迟到时间很短很短】
    1. 延迟数据
      基于事件时间窗口计算时
      数据到达时,窗口已经计算,如果会再次触发窗口计算,这条数据就是延迟数据
      AllowedLateness
    1. 迟到数据
      基于事件时间窗口计算时
      数据到达时,窗口已经计算,并且销毁数据,此条数据就是迟到数据

6.基于事件时间的会话窗口对乱序、延迟和迟到数据的处理(重要)

Flink Window窗口计算中,如果是基于事件时间的会话窗口,不存在乱序、延迟和迟到数据的处理。
数据到达时,如果窗口触发计算并且销毁,直接属于下一个窗口中数据,参与计算

Flink1.11版本使用

Flink 1.11之前版本,基于事假时间窗口计算时,需要显示设置(默认时间语义为处理时间ProcessTime)时间语义,并且从1.12版本开始,基于时间窗口计算API也发生变化,与以前版本稍有不同

  • step1 显示设置时间语义
      // 1. 执行环境-env
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        //todo step1 显示设置时间时间语义
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
  • step2 指定数据的事件时间字段,且必须是long类型
crossRoadEventStream
                .assignTimestampsAndWatermarks(
                // 设置最大乱序时间maxOutOfOrderness 为1min
                new BoundedOutOfOrdernessTimestampExtractor<CrossRoadEvent>(Time.minutes(1)) {
  • step3 设置窗口和聚合函数
  • 设置watermark水印

        //todo step2 指定数据中事件时间的字段,必须为long类型
        SingleOutputStreamOperator<CrossRoadEvent> timeStream = crossRoadEventStream
                .assignTimestampsAndWatermarks(
                // 设置最大乱序时间maxOutOfOrderness 为1min
                new BoundedOutOfOrdernessTimestampExtractor<CrossRoadEvent>(Time.minutes(1)) {
  • 设置侧边流和 Allowed Lateness
// 设置滚动窗口TumblingEventTimeWindows大小为10min 并且设置窗口聚合函数
        SingleOutputStreamOperator<CrossRoadReport> reportStream = timeStream
                .keyBy(CrossRoadEvent::getRoadId)
                .window(TumblingEventTimeWindows.of(Time.minutes(10)))
                //设置侧边流
                .sideOutputLateData(lateOutputTag)
                // 设置allowedLateness 当窗口计算后,保存一段时间数据,当窗口中有数据达到时,继续触发计算
                .allowedLateness(Time.minutes(2))

Flink1.13版本使用

相关文章

网友评论

      本文标题:Flink_window窗口计算如何解决乱序,延迟,迟到数据问题

      本文链接:https://www.haomeiwen.com/subject/jgjogrtx.html