Flink笔记-Watermark

一、两种watermark类型

1、Periodic(常用)

        周期性(一定时间间隔或者到达一定记录数)生成watermark。

        对应接口:AssignerWithPeriodicWatermarks

        必须结合时间或者累计条数两个维度,否则在极端情况下会有很大的延时。

        两个个抽象类:

                AscendingTimestampExtractor

                BoundedOutOfOrdernessTimestampExtractor(常用)

2、Punctuated(不常用)

        在满足自定义条件时生成watermark,每个元素都有一次机会判断是否生成watermark)

        对应接口:AssignerWithPunctuatedWatermarks

        在TPS很高的生产环境下会产生大量的 Watermark,可能在一定程度上对下游算子造成一定的压力,只有在实时性很高的场景才会选择这种方式来进行生成水印。

        在flink高版本已经标记为废弃。

二、代码

public class EventTimeAndWatermarkStream{
    public static void main(String[] args) {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(3);

        // 采用事件时间
        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

        FlinkKafkaConsumer010<String> source = new FlinkKafkaConsumer010<>("dwd", new SimpleStringSchema(), KafkaUtils.comsumerProps());
        DataStreamSource<String> sourceStream = env.addSource(source);

        // 设置watermark
        SingleOutputStreamOperator<String> sourceWithWatermarkStream = sourceStream.assignTimestampsAndWatermarks(new AssignerWithPeriodicWatermarks<String>() {

            private long currentMaxEventTime = 0L;

            /*
            生成watermark
             */
            @Override
            public Watermark getCurrentWatermark() {
                long maxOutOfOrderness = 2000;
                return new Watermark(currentMaxEventTime - maxOutOfOrderness);
            }

            /*
            生成事件时间
             */
            @Override
            public long extractTimestamp(String line, long l) {
                DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

                JSONObject item = JSON.parseObject(line);
                String timeString = item.getOrDefault("time", "20210101000000").toString();
                long time = LocalDateTime.parse(timeString, format).toEpochSecond(ZoneOffset.of("+8")) * 1000;
                currentMaxEventTime = Math.max(currentMaxEventTime, time);
                return time;
            }
        });

        sourceWithWatermarkStream.print();
        env.execute();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值