Flink之Watermark策略代码模板

方式 作用
WatermarkStrategy.noWatermarks() 不生成watermark
WatermarkStrategy.forMonotonousTimestamps() 紧跟最大事件时间watermark生成策略
WatermarkStrategy.forBoundedOutOfOrderness() 允许乱序watermark生成策略
WatermarkStrategy.forGenerator() 自定义watermark生成策略
  • noWatermarks

    java 复制代码
    public class FlinkWaterMark throws Exception {
      public static void main(String[] args) throws Exception {
          StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
          // 获取数据源
          DataStreamSource<String> socketSource = env.socketTextStream("localhost", 8888);
          // 构造watermark生成策略,选择不生成watermark
          WatermarkStrategy<UserEvent2> watermark = WatermarkStrategy.noWatermarks();
          // 将构造完成的watermark分配给数据流
          SingleOutputStreamOperator<UserEvent2> source = socketSource.assignTimestampsAndWatermarks(watermark);
          // ...
          env.execute();
      }
    }

    关于noWaterMarks()的使用没有太多内容.

  • forMonotonousTimestamps

    java 复制代码
    public class FlinkWaterMark throws Exception {
      public static void main(String[] args) throws Exception {
          StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
          // 获取数据源
          DataStreamSource<String> socketSource = env.socketTextStream("localhost", 8888);
          // 构造watermark, 使用紧跟最大事件时间策略
          WatermarkStrategy<String> watermark = WatermarkStrategy.<String>forMonotonousTimestamps()
                  // 抽取时间时间, 根据数据中实际情况选择
                  .withTimestampAssigner(new SerializableTimestampAssigner<String>() {
                      @Override
                      public long extractTimestamp(String element, long recordTimestamp) {
                          /**
                           * 这里是样例代码,实际情况根据具体业务具体数据特性抽取对应的时间
                           **/
                          String time = element.split(",")[0];
                          long timestamp = Long.parseLong(time);
                          return timestamp;
                      }
                  });
          // 将构造完成的watermark分配给数据流
          SingleOutputStreamOperator<UserEvent2> source = socketSource.assignTimestampsAndWatermarks(watermark);
          // ...
          env.execute();
      }
    }

    对于forMonotonousTimestamps()可说内容并不多,如果选择了forMonotonousTimestamps这种方式就必须保证事件时间严格有序,如果出现乱序的情况可能存在大量数据丢失的问题.
    通过源码内容可以看到forMonotonousTimestamps底层也是使用的forBoundedOutOfOrderness方式,只不过将容错时间设置为了0,源码如下:

    java 复制代码
    // 首先看这里,继承的BoundedOutOfOrdernessWatermarks
    public class AscendingTimestampsWatermarks<T> extends BoundedOutOfOrdernessWatermarks<T> {
    
      /** Creates a new watermark generator with for ascending timestamps. */
      public AscendingTimestampsWatermarks() {
          super(Duration.ofMillis(0)); // 这里将容错时间设置为了0
      }
    }
  • forBoundedOutOfOrderness

    java 复制代码
    public class FlinkWaterMark throws Exception {
      public static void main(String[] args) throws Exception {
          StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
          // 获取数据源
          DataStreamSource<String> socketSource = env.socketTextStream("localhost", 8888);
          // 构造watermark, 使用允许水位线乱序策略,并设置最大容错时间为2s
          WatermarkStrategy<String> watermark = WatermarkStrategy.forBoundedOutOfOrderness(Duration.ofMillis(2000))
                  // 抽取时间时间, 根据数据中实际情况选择
                  .withTimestampAssigner(new SerializableTimestampAssigner<String>() {
                      @Override
                      public long extractTimestamp(String element, long recordTimestamp) {
                          /**
                           * 这里是样例代码,实际情况根据具体业务具体数据特性抽取对应的时间
                           **/
                          String time = element.split(",")[0];
                          long timestamp = Long.parseLong(time);
                          return timestamp;
                      }
                  });
          // 将构造完成的watermark分配给数据流
          SingleOutputStreamOperator<UserEvent2> source = socketSource.assignTimestampsAndWatermarks(watermark);
          // ...
          env.execute();
      }
    }

    对于允许乱序策略前面文章有介绍过其原理,比如代码中设置容错时间为2S,那么前后的数据差最大只能是2S,如果差值大于2S,后来的这条数据就会被抛弃.

相关推荐
武子康4 小时前
大数据-239 离线数仓 - 广告业务实战:Flume 导入日志到 HDFS,并完成 Hive ODS/DWD 分层加载
大数据·后端·apache hive
字节跳动数据平台1 天前
代码量减少 70%、GPU 利用率达 95%:火山引擎多模态数据湖如何释放模思智能的算法生产力
大数据
得物技术1 天前
深入剖析Spark UI界面:参数与界面详解|得物技术
大数据·后端·spark
大大大大晴天1 天前
Flink生产问题排障-HBase NotServingRegionException
flink·hbase
武子康1 天前
大数据-238 离线数仓 - 广告业务 Hive分析实战:ADS 点击率、购买率与 Top100 排名避坑
大数据·后端·apache hive
武子康2 天前
大数据-237 离线数仓 - Hive 广告业务实战:ODS→DWD 事件解析、广告明细与转化分析落地
大数据·后端·apache hive
大大大大晴天2 天前
Flink生产问题排障-Kryo serializer scala extensions are not available
大数据·flink
武子康4 天前
大数据-236 离线数仓 - 会员指标验证、DataX 导出与广告业务 ODS/DWD/ADS 全流程
大数据·后端·apache hive
武子康5 天前
大数据-235 离线数仓 - 实战:Flume+HDFS+Hive 搭建 ODS/DWD/DWS/ADS 会员分析链路
大数据·后端·apache hive
DianSan_ERP6 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet