【深入浅出flink】第15篇:flink第一个窗口的起始点和窗口的偏移量,你知道怎么计算吗?

本文深入探讨Flink中窗口的起始点和偏移量计算,以滚动时间窗口为例,通过源码解析和实际代码测试,解释窗口范围的确定以及offset在调整时区和处理迟到数据中的应用。测试部分展示了如何验证窗口计算逻辑,并讨论了allowedLateness和sideOutputLateData对窗口处理迟到数据的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,我是雷恩Layne,这是《深入浅出flink》系列的第十五篇文章,希望能对您有所收获O(∩_∩)O


通常,我们通过dataStream.timeWindow或在dataStream.window传入一个窗口分配器来定义一个窗口。那么,第一个窗口的起点是什么,窗口的偏移量又是什么?假如,将第一个窗口的起点记为start,窗口大小为size,那么第一个窗口的范围是[start,start+size),后面的窗口范围也可以定下来,在flink中是怎么算的呢?

源码分析

以滚动时间窗口为例,我们来看看dataStream.timeWindow的源码

public WindowedStream<T, KEY, TimeWindow> timeWindow(Time size) {
   
   
	if (environment.getStreamTimeCharacteristic() == TimeCharacteristic.ProcessingTime) {
   
   
		return window(TumblingProcessingTimeWindows.of(size));
	} else {
   
   
		return window(TumblingEventTimeWindows.of(size));
	}
}

生产环境下,一般使用TimeCharacteristic.EventTime语义,所以上面代码通过TumblingEventTimeWindows.of(size)返回一个TumblingEventTimeWindows(滚动时间窗口),窗口的起点和偏移量就在TumblingEventTimeWindows类中定义的。

TumblingEventTimeWindows中的assignWindows方法定义了窗口范围的计算公式:

@Override
public Collection<TimeWindow> assignWindows(Object element, long timestamp, WindowAssignerContext context) {
   
   
	if (timestamp > Long.MIN_VALUE) {
   
   
		// Long.MIN_VALUE is currently assigned when no timestamp is present
		long start = TimeWindow.getWindowStartWithOffset(timestamp, offset, size);
		return Collections.singletonList(new TimeWindow(start, start + size));
	} else {
   
   
		throw new RuntimeException("Record has Long.MIN_VALUE timestamp (= no timestamp marker). " +
				"Is the time characteristic set to 'ProcessingTime', or did you forget to call " +
				"'DataStream.assignTimestampsAndWatermarks(...)'?");
	}
}

assignWindows用来分配Flink流处理中多个窗口的起止点,起点start计算如下:

long start = TimeWindow.getWindowStartWithOffset(timestamp, offset
### 如何在 Apache Flink 中实现基于时间的滑动窗口 为了实现在 Apache Flink 中的时间驱动型滑动窗口,开发者通常会利用 `TimeWindow` 类及其相关的方法来指定窗口的行为。具体而言,通过调用 `timeWindow()` 函数并设置相应的参数可以创建一个滑动窗口实例[^1]。 对于想要构建具有特定持续时间滑动步长的滑动窗口的应用程序来说,下面给出了一段 Python 代码作为示范: ```python from pyflink.dataset import ExecutionEnvironment from pyflink.table import BatchTableEnvironment, TableConfig from pyflink.table.window import Slide from pyflink.table.descriptors import Schema, OldCsv, FileSystem env = ExecutionEnvironment.get_execution_environment() t_config = TableConfig() t_env = BatchTableEnvironment.create(env, t_config) # 假设有一个名为 'my_table' 的表已经注册好,并且有字段 'rowtime' # 这里我们定义了一个每5秒滑动一次、窗口大小为10秒的滑动窗口聚合查询 result = t_env.from_path('my_table') \ .window(Slide.over("10.seconds").every("5.seconds").on("rowtime").as_("w")) \ .group_by("w") \ .select("avg(value), w.start as window_start, w.end as window_end") # 输出结果至文件系统或其他目的地... ``` 上述例子展示了怎样设定一个拥有给定尺寸及时移量的滑动窗口;这里采用的是 SQL-like API 来表达逻辑。值得注意的是,实际开发过程中可能还需要考虑更多细节,比如如何处理迟到的数据等[^4]。 另外,关于窗口起始时刻的具体计算方式,可以通过 `TimeWindow#getWindowStartWithOffset` 方法完成。此函数接收三个输入参数——时间戳(即当前记录所属的实际发生瞬间)、偏移量以及窗口宽度,并返回调整后的窗口位置。其核心算法在于先减去偏移再求模数最后加上该偏移值以确保得到正确的边界。 #### 计算窗口开始结束时间 当涉及到具体的窗口时间段界定时,则依赖于如下公式来进行转换: \[ \text{window\_start}=\left(\text{timestamp}-\text{(}\text{timestamp}-\text{offset}+\text{windowSize)} \% \text{windowSize}\right)+\text{offset} \] 而窗口结束时间为: \[ \text{window\_end}= \text{window\_start} + \text{windowSize} \] 这些运算可以在内部自动执行,因此用户一般不需要手动编写这部分逻辑除非是在某些特殊场景下需要定制化行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷恩Layne

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值