Flink Event Time 和WaterMark

Flink Event Time 和WaterMark

ProcessingTime

下面有一个窗口大小为 10s,步长为 5s的滑动窗口 进行数据统计。假设数据源在第13秒(2次)、第16秒分别生成了3条A类型的消息(小时和分钟先不管)。如下:
在这里插入图片描述
这些消息将按如下方式落在窗口中。在第13秒生成的前两条消息将同时落在窗口1[5s-15s]和窗口2[10s-20s]中,在第16秒生成的第三条消息将落在窗口2[10s-20s]和窗口3[15s-25s]中。每个窗口发出的最终计数分别为(a,2)、(a,3)和(a,1)。
窗口收集
如果其中一条消息(在第13s生成)延迟6s(19s)到达,那么按上图结算的话,那么这个数据就会落在window2(10-20s)和window315-25的窗口里面,如下:
在这里插入图片描述
结果导致window3 和window1的统计结果不对,下面我们看下以EventTime解决这个问题

EventTime

对于使用 EventTime 处理,需要从消息中(事件)提取事件的时间信息,实现 TimestampAssigner extractTimestamp方法。如下:

 env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
 public long extractTimestamp(Tuple3<String, Long, Integer> element, long previousElementTimestamp) {
    return element.f1;
 }

我们使用了event time 进行处理后,产生的结果如下:

在这里插入图片描述
我们发现 window 2 和 window3 的统计结果对的,因为采用了事件的时间,这个事件所携带的事件是13s的因此不会被统计到window3(15s-20s)这个窗口中,但是window 1 没有统计因为窗口已经结算完成了(15s)。

ps:其实window2 也不能说统计对的,因为13s延迟到19s只是恰好在这个窗口里面,假如是延迟8s呢?是不是window2窗口就没有这条数据了。

下面我们使用 watermark 解决这个问题。

WaterMark

WaterMark 对flink 而言是灰常重要的,他的本质就是一个时间戳,当算子收到这个时间戳后,就不会在处理这个时间戳以下的数据了,就是何时不再等待更早的数据了。
我们可以根据事件的event-time,计算出Watermark。在上一个demo 中,没有设置延迟的时间,我们现在将WaterMark设置为:当前时间-5 秒,相当于延迟5秒结算,所以第一个窗口[5s-15s]将仅在第20秒进行结算。同样,窗口[10s-20s]将在第25秒进行结算,以此类推。

private long  currentMaxTimestamp = 0l;
private final long maxOutOfOrderness = 5000l;
@Nullable
@Override
public Watermark getCurrentWatermark() {
    return new Watermark(currentMaxTimestamp - maxOutOfOrderness);
}
@Override
public long extractTimestamp(Tuple3<String, Long, Integer> element, long previousElementTimestamp) {
    long timestamp= element.f1;
    currentMaxTimestamp = Math.max(timestamp, currentMaxTimestamp);
    return timestamp;
}

统计结果如下:
延迟结算
对于最大延迟时间设置需要根不同的业务和场景设置,设置太小会丢弃延迟的数据。太大会导致窗口一直处于等待状态。
最后留一个关系图供参考:
在这里插入图片描述
Thanks for reading 。
参考
[1]: https://ci.apache.org/projects/flink/flink-docs-release-1.8/dev/event_time.html
[2]: https://www.ververica.com/blog/how-apache-flink-manages-kafka-consumer-offsets
[3]: https://blog.youkuaiyun.com/xorxos/article/details/80715113

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值