flink中通用的watermark设置代码模板(基于1.14版本)

文章介绍了ApacheFlink中处理乱序事件的watermark策略,包括允许一定延迟的BoundedOutOfOrderness策略、严格有序的MonotonousTimestamps策略以及不使用watermark和自定义watermark的情况。提供了在source和map算子中设置watermark的代码示例。
摘要由CSDN通过智能技术生成

flink中通用的watermark设置代码模板,

watermark生成策略通常有四种,长用的为第一、二种

  • 一、WatermarkStrategy.forBoundedOutOfOrderness(Duration.ofMillis(3000)) 允许乱序的watermark // Duration.ofMillis(3000) 设置容忍时间为3000ms
  • 二、WatermarkStrategy.forMonotonousTimestamps()
    完全不容忍乱序,紧跟最大事件时间,等于第一个括号内填0,调的就是一的API
  • 三、WatermarkStrategy.noWatermarks() 不使用watermark
  • 四、WatermarkStrategy.forGenerator() 自定义watermark

通常会在source直接设置watermark,后续算子会传递依赖source的watermark

source设置watermark代码模板示例:

package com.syxStudy;

import java.time.Duration;

public class WaterMarkAPI {
    public static void main(String[] args) {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 数据源获取socket文本流,假设数据格式为 1684243149,syx,18
        DataStreamSource<String> sourceStream = env.socketTextStream("192.168.xx.xxx", 9999);
        //构造一个watermark生成策略
        WatermarkStrategy<String> stringWatermarkStrategy = WatermarkStrategy.<String>forBoundedOutOfOrderness(Duration.ofMillis(3000)).withTimestampAssigner(new SerializableTimestampAssigner<String>() {
            @Override
            public long extractTimestamp(String s, long l) {
                return Long.parseLong(s.split(",")[0]);
            }
        });
        //将构造的watermark算子分配给source算子。不止可以在source分配watermark,也可以从后续算子开始生成watermark。一般来说是从source生成
        sourceStream.assignTimestampsAndWatermarks(stringWatermarkStrategy);
    }
}

在map算子中生成watermark(不常用)

package com.syxStudy;

import java.time.Duration;

public class WaterMarkAPI {
    public static void main(String[] args) {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        // 数据源获取socket文本流,假设数据格式为 1684243149,syx,18
        DataStreamSource<String> sourceStream = env.socketTextStream("192.168.xx.xxx", 9999);
        
        //在map算子计算逻辑
        SingleOutputStreamOperator<EventBean> map_func = sourceStream.map(new MapFunction<String, EventBean>() {
            @Override
            public EventBean map(String s) throws Exception {
                String[] split_socket_txt = s.split(",");
                return new EventBean(Long.parseLong(split_socket_txt[0]), split_socket_txt[1], Integer.parseInt(split_socket_txt[0]));
            }
        }).returns(EventBean.class);

        //添加到map算子中
        SingleOutputStreamOperator<EventBean> map_add_watermark = map_func.assignTimestampsAndWatermarks(
                WatermarkStrategy.<EventBean>forMonotonousTimestamps()
                        .withTimestampAssigner(new SerializableTimestampAssigner<EventBean>() {
                            @Override
                            public long extractTimestamp(EventBean eventBean, long l) {
                                return eventBean.getTimestamp();
                            }
                        })
        );
    }
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class EventBean{
    private Long timestamp;
    private String name;
    private int age;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FlinkWatermark是用于处理事件时间的机制,用于表示事件时间进展到了哪个时间点。Watermark的生成需要一个Watermark Generator,而Watermark Generator又由Timestamp Assigner和Watermark Generator两部分组成。 具体来说,Timestamp Assigner用于从数据提取事件时间,而Watermark Generator则用于根据事件时间生成WatermarkWatermark Generator有两种生成方式:基于数据的Timestamp Assigner和基于时间的Watermark Generator。 在Flink,可以通过实现WatermarkGenerator接口来自定义Watermark Generator。WatermarkGenerator接口有两个方法:onEvent和onPeriodicEmit。onEvent方法会在每个事件到达时被调用,用于更新Watermark,而onPeriodicEmit方法会周期性地触发,用于生成Watermark。 下面是一个示例代码,演示如何在Flink设置Watermark: ```java public class MyWatermarkGenerator implements WatermarkGenerator<MyEvent> { private long maxTimestamp = Long.MIN_VALUE; @Override public void onEvent(MyEvent event, long eventTimestamp, WatermarkOutput output) { // 更新maxTimestamp maxTimestamp = Math.max(maxTimestamp, eventTimestamp); } @Override public void onPeriodicEmit(WatermarkOutput output) { // 生成Watermark output.emitWatermark(new Watermark(maxTimestamp - 5000)); } } ``` 在上面的代码,我们实现了WatermarkGenerator接口,并重写了onEvent和onPeriodicEmit方法。在onEvent方法,我们更新了maxTimestamp,而在onPeriodicEmit方法,我们生成了Watermark,并通过output.emitWatermark方法将其发送出去。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值