java Flink(三十五)Flink的watermark设置以及部分实现类

watermark(水位线)是Flink里边的相当重要的存在,是Flink处理乱序数据的重要组成。

Flink理论上定义了三种watermark广播机制(【2种生成水印的策略】【如果生成的watermark是null,或者小于之前的watermark,则该watermark不会发往下游】)。

首先看看它的组成:

 

AssignerWithPunctuatedWatermarks(为每条消息都会尝试生成水印)

AssignerWithPeriodicWatermarks(周期性的生成水印,不会针对每条消息都生成)(常用)

还有第三种策略是 无为策略:不设定watermark策略。

这两种策略的源码分析参考https://www.cnblogs.com/ljygz/p/11435243.html

AssignerWithPeriodicWatermarks 实例:

.assignTimestampsAndWatermarks(new AssignerWithPeriodicWatermarks<Tuple2<String, String>>() {
                    //定义watermark乱序等待时间2s,即允许数据的最大乱序时间
                    private long maxOutofOrderness  = 2 * 1000;
                    // 观察到的最大时间戳
                    private long currentMaxTs = Long.MIN_VALUE;

                    @Nullable
                    public Watermark getCurrentWatermark() {
                        //生成具有2s容忍度的水位线
                        return new Watermark(currentMaxTs-maxOutofOrderness );
                    }
                    // 先调用该函数 previousElementTimestamp代表
                    public long extractTimestamp(Tuple2<String, String> element, long previousElementTimestamp) {
                        long currentTime = previousElementTimestamp;
                        // 更新最大的时间戳
                        currentTime = Math.max(currentMaxTs, currentTime);
                        // 返回记录的时间戳
                        return currentTime;
                    }
                })

再看看实现接口的几个抽象类:

关于AscendingTimestampExtractor,一般是在数据集的时间戳是单调递增的且没有乱序时使用,该方法使用当前的时间戳生成水位线

.assignTimestampsAndWatermarks(new AscendingTimestampExtractor<UserBehavior>() {
                    @Override
                    public long extractAscendingTimestamp(UserBehavior element) {
                        return element.timestamp*1000;
                    }
                });

 关于BoundedOutOfOrdernessTimestampExtractor,是在数据集中存在乱序数据的情况下使用,即数据有延迟(任意新到来的元素与已经到来的时间戳最大的元素之间的时间差),这种方式可以接收一个表示最大预期延迟参数,具体如下:

.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor<UserBehavior>(Time.seconds(10)) {
                    @Override
                    public long extractTimestamp(UserBehavior element) {
                        return element.timestamp*1000;
                    }
                } );

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink中,Watermark是用于处理事件时间的机制,用于表示事件时间进展到了哪个时间点。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、付费专栏及课程。

余额充值