Flink时间语义和watermark

一、时间语义

Event Time:事件创建的时间

Ingestion Time:数据进入Flink的时间

Processing Time:执行算子操作的本地系统时间,与机器相关

设置时间语义

StreamExecutionEnvironment environment = StreamExecutionEnvironment.getExecutionEnvironment();
environment.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

当Flink以Event Time模式处理数据流时,它会根据数据里的时间戳来处理基于时间的算子

考虑到网络或者分布式等原因,现实数据流的数据可能是乱序的

举个例子:

数据流有如下数据:1,2,3,4,5,6  当5到了触发window算子操作

理想情况是5到了,那么比我小的都到了,触发window操作没问题

但是实际情况,数据有可能乱序,5到了,不一定比5小的都到,如下图所示3,2都没到

如何解决乱序数据带来的问题?

flink引入了watermark

二、waterMark(水位线)

对于乱序数据流而言,遇到一个时间戳达到窗口关闭时间,不应该立刻触发窗口计算,而是等待一段时间,等迟到的数据来了再关闭窗口。

watermark是一种衡量Event Time进展的机制,可以设定延迟触发

数据流中的watermark用于表示事件的时间小于watermark的数据都已经到达,因此window的执行也是由watermark触发

1、watermark特点

(1)watermark是一条特殊的数据记录

(2)watermark必须单调递增,以确保任务的事件时间时钟在向前推进

(3)watermark与数据的时间戳相关

2、程序中使用watermark

Flink暴露TimestampAssigner接口供自定义实现抽取时间戳和生成watermark

BoundedOutOfOrdernessTimestampExtractor是处理乱序数据

dataStream.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<String>(Time.seconds(1)) {
    @Override
    public long extractTimestamp(String element) {
        JSONObject jsonObject=JSONObject.parseObject(element);
        Long timestamp = jsonObject.getLong("timestamp");//获取事件时间戳
        return timestamp;
    }
});

(1)AssignerWithPeriodicWatermarks

       1)周期性的生成watermark,系统会周期性的将watermark插入到流中

       2)默认周期200毫秒,可以使用ExecutionConfig方法设置

environment.getConfig().setAutoWatermarkInterval(1000);

 

       3)升序和前面乱序的处理BoundedOutOfOrdernessTimestampExtractor都是基于周期性watermark

       举例:

dataStream.assignTimestampsAndWatermarks(new AssignerWithPeriodicWatermarks<String>(){
    long bound=60*1000;//延迟1分钟
    long maxTimestamp=0;
    @Override
    public long extractTimestamp(String element, long previousElementTimestamp) {
        JSONObject jsonObject=JSONObject.parseObject(element);
        Long timestamp = jsonObject.getLong("timestamp");//获取事件时间戳
        if(maxTimestamp==0){
            maxTimestamp=timestamp;
        }else{
            maxTimestamp=Math.max(maxTimestamp,timestamp);
        }
        return timestamp;
    }
    @Nullable
    @Override
    public Watermark getCurrentWatermark() {
        return new Watermark(maxTimestamp-bound);
    }
});

(2)AssignerWithPunctuatedWatermarks

         没有时间周期规律,可打断生成watermark

         举例:

dataStream.assignTimestampsAndWatermarks(new AssignerWithPunctuatedWatermarks<String>(){
    long bound=60*1000;//延迟1分钟
    @Override
    public long extractTimestamp(String element, long previousElementTimestamp) {
        JSONObject jsonObject=JSONObject.parseObject(element);
        Long timestamp = jsonObject.getLong("timestamp");//获取事件时间戳
        return timestamp;
    }

    @Nullable
    @Override
    public Watermark checkAndGetNextWatermark(String lastElement, long extractedTimestamp) {
        JSONObject jsonObject=JSONObject.parseObject(lastElement);
        String name = jsonObject.getString("name");
        if(name.equals("zs")) {
            return new Watermark(extractedTimestamp-bound);
        }
        return null;
    }
});
发布了59 篇原创文章 · 获赞 2 · 访问量 2061

猜你喜欢

转载自blog.csdn.net/zuodaoyong/article/details/103605597