SourceFunction中生成TimeStamp和Watermark

SourceFunction中定义了一个void run(SourceContext ctx)方法来启动数据源,SourceContext对象中定义了数据源发送事件数据并生成TimeStamp的方法:

  • void collectWithTimeStamp(T element,long timestamp)
    第一个参数element代表要发送的元素,第二个参数timestamp代表这个元素对应的时间戳。这个方法只有在设置TimeCharacteristic为EventTime时才有效。当设置为ProcessingTime时,设置的TimeStamp直接忽略。
  • void emitWatermark(Watermark mark)
    该方法接受一个Watermark类型的参数mark,当发送一个时间戳为T的mark时,表示该数据流上不会再有timestamp小于等于T这个时间的任何事件记录。一般来说,这个mark值T是基于最大的timestamp来生成的,比如以最大timestamp减去1。

代码

package com.atguigu.apitest.example;

import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.streaming.api.TimeCharacteristic;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.functions.source.SourceFunction;
import org.apache.flink.streaming.api.watermark.Watermark;
import java.util.Arrays;

/**
 * @author zhanganjie
 * @version 1.0
 * @description: TODO
 * @date 2021/11/29 12:16
 */
public class Demo01 {
    public static void main(String[] args) throws Exception {
        //创建流处理环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        //设置时间时间EventTime语义
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
        //并行度为1
        env.setParallelism(1);
        //演示数据
        Tuple3[] input = {
                Tuple3.of("user1",1000L,1),
                Tuple3.of("user1",1999L,2),
                Tuple3.of("user1",2000L,3),
                Tuple3.of("user1",2100L,4),
                Tuple3.of("user1",2130L,5),
        };
        //通过示例数据生成DataStream
        DataStream<Tuple3<String,Long,Integer>> source = env.addSource(
                //SourceFunction中进行时间戳分配和水位线生成
                new SourceFunction<Tuple3<String, Long, Integer>>() {
                    @Override
                    public void run(SourceContext<Tuple3<String, Long, Integer>> sourceContext) throws Exception {
                        Arrays.asList(input).forEach(tp3 -> {
                            //指定时间戳
                            System.out.println("collectWithTimeStamp:"+ (long)tp3.f1);
                            sourceContext.collectWithTimestamp(tp3, (long) tp3.f1);
                            //发送水位线
                            System.out.println("emitWatermark:"+ ((long)tp3.f1-1));
                            sourceContext.emitWatermark(new Watermark((long) tp3.f1-1));

                            System.out.println("*******************************************************");
                        });
                        //代表结束标志
                        sourceContext.emitWatermark(new Watermark(Long.MAX_VALUE));
                    }

                    @Override
                    public void cancel() {

                    }
                }
        );
        //结果打印
        source.print();
        env.execute();


    }
}

对于代码中input对象代表一个数据集,通过addsource可以添加自定义的SourceFunction,在内部的run方法中,通过遍历input数据集,对于每个数据元素,调用sourceContext.collectWithTimstamp(tp3,(long)tp3.f1)来分配时间戳,其中参数tp3代表需要发送的数据,而tp3.f1代表获取数据源中的时间戳字段,并将其类型转换成Llong类型。

对于每个数据元素,再调用source.emitWatermark(new Watermark((long)tp3.f1 - 1))来生成Watermark,其规则为当前元素的时间戳减去1,代表1毫秒的延迟。
生成结果
在这里插入图片描述
从上述结果中可以看出,每次接受到一个事件数据,都会调用生成Timestamp和Watermark,其中生成的Watermark值为当前事件的Timestamp减去1。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值