【Flink入门(5)】Flink的时间语义与Watermark

【时间】2022.06.07 周二

【题目】【Flink入门(5)】Flink的时间语义与Watermark

本专栏是尚硅谷Flink课程的笔记与思维导图。

目录

引言

一、时间(Time)语义

 三种时间语义

二、Watermark(水位线)

2.1 概述

乱序数据的影响

2.2 特点

2.3 Watermark相关知识

1)向下游传递

2)在stream中引入(代码)

3)设置合适的WaterMark延时时间 

4)窗口起始点计算

2.4 Flink处理迟到数据的3层保障

总思维导图


引言

  1. flink中有3种时间语义,这里主要讲EvenTime事件时间,从数据的时间戳中提取,属于事件创建(数据产生)的时间,区别于数据到达时间(Ingestion Time)和处理时间(Processing Time)。 
  2. Watermark(水位线)是一种处理乱序数据的机制,相当于扩宽window窗口以处理迟到数据。

一、时间(Time)语义

 三种时间语义

二、Watermark(水位线)

2.1 概述

乱序数据的影响

2.2 特点

 

WaterMark的作用是延迟关闭前一个窗口的时间,以处理迟到的数据:

2.3 Watermark相关知识

1)向下游传递

上游Task的watermark广播给下游Task,下游Task取最小WM:

2)在stream中引入(代码)

 例子:

public class WindowTest3_EventTimeWindow {
  public static void main(String[] args) throws Exception {
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    // Flink1.12.X 已经默认就是使用EventTime了,所以不需要这行代码
    //        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    env.getConfig().setAutoWatermarkInterval(100);

    // socket文本流
    DataStream<String> inputStream = env.socketTextStream("localhost", 7777);

    // 转换成SensorReading类型,分配时间戳和watermark
    DataStream<SensorReading> dataStream = inputStream.map(line -> {
      String[] fields = line.split(",");
      return new SensorReading(fields[0], new Long(fields[1]), new Double(fields[2]));
    })
      //              
      // 旧版 (新版官方推荐用assignTimestampsAndWatermarks(WatermarkStrategy) )
      // 升序数据(不乱序)设置事件时间和watermark
      //.assignTimestampsAndWatermarks(new AscendingTimestampExtractor<SensorReading>() {
      //  @Override
      //  public long extractAscendingTimestamp(SensorReading element) {
      //    return element.getTimestamp() * 1000L;
      //  }
      //})
      
      // 旧版 (新版官方推荐用assignTimestampsAndWatermarks(WatermarkStrategy) )
      // 乱序数据设置时间戳和watermark
      .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<SensorReading>(Time.seconds(2)) {//需要传入参数:乱序程度
        @Override
        public long extractTimestamp(SensorReading element) {
          return element.getTimestamp() * 1000L; //毫秒
        }
      });

    OutputTag<SensorReading> outputTag = new OutputTag<SensorReading>("late") {
    };

    // 基于事件时间的开窗聚合,统计15秒内温度的最小值
    SingleOutputStreamOperator<SensorReading> minTempStream = dataStream.keyBy("id")
      .timeWindow(Time.seconds(15))
      .allowedLateness(Time.minutes(1))
      .sideOutputLateData(outputTag)
      .minBy("temperature");

    minTempStream.print("minTemp");
    minTempStream.getSideOutput(outputTag).print("late");

    env.execute();
  }
}

3)设置合适的WaterMark延时时间 

4)窗口起始点计算

其中offset是时区偏移量。

2.4 Flink处理迟到数据的3层保障

例子:

public class WindowTest3_EventTimeWindow {
  public static void main(String[] args) throws Exception {
    StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

    env.setParallelism(1);

    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
    env.getConfig().setAutoWatermarkInterval(100);

    // socket文本流
    DataStream<String> inputStream = env.socketTextStream("localhost", 7777);

    // 转换成SensorReading类型,分配时间戳和watermark
    DataStream<SensorReading> dataStream = inputStream.map(line -> {
      String[] fields = line.split(",");
      return new SensorReading(fields[0], new Long(fields[1]), new Double(fields[2]));
    })
      
      // 乱序数据设置时间戳和watermark
      .assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<SensorReading>(Time.seconds(2)) {
        @Override
        public long extractTimestamp(SensorReading element) {
          return element.getTimestamp() * 1000L;
        }
      });

    OutputTag<SensorReading> outputTag = new OutputTag<SensorReading>("late") {
    };

    // 基于事件时间的开窗聚合,统计15秒内温度的最小值
    SingleOutputStreamOperator<SensorReading> minTempStream = dataStream.keyBy("id")
      .timeWindow(Time.seconds(15)) //时间窗口大小15s
      .allowedLateness(Time.minutes(1))//允许延时1m,这是基于处理时间的(即窗口执行时间),窗口操作后,在1min内,每来一个迟到数据,就输出一个结果。
      .sideOutputLateData(outputTag)//测输出流
      .minBy("temperature");

    minTempStream.print("minTemp");
    minTempStream.getSideOutput(outputTag).print("late");

    env.execute();
  }
}

总思维导图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值