Flink中水位线的时间戳为何要减一

Flink中的水位线的时间戳为何总要减一

最近在回顾flink相关知识,在尚硅谷flink的笔记中看到一段关于flink水位线的时间戳减一的介绍:

乱序流中生成的水位线的时间戳,其实是当前数据中 最大时间戳 – 延迟时间 – 1,这里的单位是毫秒。为什么要减 1 毫秒呢?我们可以回想一下水位线的特点:时间戳为 t 的水位线,表示时间戳≤t 的数据全部到齐,不会再来了。假设数据中时间戳为 7 秒的数据到来时,不能说≤7s 的数据全部到来了,之后其实是还有可能继续来数据中时间戳为 7 秒的数据啊,所以生成的水位线不是 7 秒,而是 6 秒 999 毫秒,这点可以在乱序流中定义时间戳策略相关类 BoundedOutOfOrdernessWatermarks 的源码中明显地看到:maxTimestamp 代表数据的最大时间戳,outOfOrdernessMillis 代表延迟时间,我们暂时考虑延迟为0。

public void onPeriodicEmit(WatermarkOutput output) {
output.emitWatermark(new Watermark(maxTimestamp - outOfOrdernessMillis - 1));

这段话其实讲的不是很明了,几乎都是在重复一点:水位线是7秒,但只接受6秒999毫秒以前的数据(即t<=6.999s)。它并没有指出为什么要这样设计。这里我经过一番思考觉得主要的原因如下:

flink默认将所有的数据都视为流数据,如下图所示:

在这里插入图片描述

数据不断出现,每一个数据都有一个时间戳。我们首先看第一个窗口,它做为数据流中最前面的数据,是有可能存在时间戳为0的数据的,作为第一个窗口,它必须包含0这个数据。该窗口的长度为10,如果时间戳为10的数据到来,那应该算第一个窗口的数据还是第二个窗口的数据呢?

假设属于第一个窗口,此时第一个窗口就不是[0,10),而是[0,10]了。注意,它不可能是(0,10],因为我们前面解释了,0是第一个数据,它必须放在第一个窗口。在窗口为[0,10]的情况下,当10这条数据到来的时候,应该属于第一个窗口是吧?但是此时第二个窗口就必须为(10,20],此时窗口就变为左开右闭了。和第一个窗口不一致。

假设属于第二个窗口,此时第一个窗口就是[0,10),第二个窗口是[10,20),这样,第一个窗口和第二个窗口都是左闭右开。

其实,我个人的理解是这样做为了使所有窗口的开闭都是相同的,方便统一的管理和编写针对窗口与水位线的逻辑。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值