【Flink】Flink 中的时间和窗口之窗口(Window)

news2025/2/26 20:07:42

1. 窗口的概念

Flink是一种流式计算引擎,主要是来处理无界数据流,数据流的数据是一直都有的,等待流结束输入数据获取所有的流数据在做聚合计算是不可能的。为了更方便高效的处理无界流,一种方式就是把无限的流数据切割成有限的数据块进行处理,这就是Flink中提到的窗口(Windows)

在Flink中,窗口就是用来处理无界流的核心。我们很容易把窗口想象成一个固定位置的,数据源源不断的流过来,到某个时间点窗口该关闭了,就停止收集数据,触发计算并输出结果。

例如,我们定义了一个时间窗口,每10秒统计一次数据,呢么就相当于把窗口放在那里,从0秒开始收集数据,到10秒时,处理当前窗口内所有的数据,输出一个结果,然后清空窗口继续收集数据;到20秒时,再对窗口内所有数据进行计算处理,输出结果;以此类推:
在这里插入图片描述
这里使用的窗口[0,10)窗口是左闭右开区间,即包含起始时间点,但不包括结束时间点。对于处理实时数据的窗口来说,这种方式存在一定问题。因为基于系统时间进行窗口关闭操作,在某些情况下可能会出现处理结果不准确或丢失部分数据的情况。例如,在一个 0-10 秒的窗口关闭后,如果还有一条时间戳为 9 秒的数据到达,则该数据将无法被正确地处理,并只能进入下一个 10-20 秒的窗口中。

然而如果我们采用事件时间语义,就会有一些费解了。由于乱序数据,我们需要设置一个延迟时间来等所有数据到齐。比如上面的例子,我们可以设置延迟时间为2秒,如下图,这样0-10秒的窗口会在时间戳为12秒的数据到来之后,才真正关闭计算输出结果,这样就可以正常包含迟到的9秒数据了。
在这里插入图片描述
但是这样一来,0-10秒的窗口不光包含了迟到的9秒数据,连11秒和12秒的数据也包含进去了。我们为了正确处理迟到数据,结果把早到的数据划分到了错误的窗口----最终结果也是错的

所以为了解决这个问题,窗口其实并不是一个框,流进来的数据被框住只能进这一个窗口。窗口而是一个桶。在Flink中,窗口可以把流切割成有限大小的多个存储桶;每个数据都会分发到对应的桶中,当到达窗口结束时间时,就对每个桶中收集的数据进行计算处理
在这里插入图片描述
在事件时间语义下,窗口的处理过程:

1. 第一个数据时间戳为2,判断之后创建第一个窗口[0,10),并将2秒数据保存进去;
2. 后续数据依次到来,时间戳均在[0,10)范围内,所以全部保存进第一个窗口
3. 11秒数据到来,判断不属于[0,10)窗口,所以创建第二个窗口[10,20),并将11秒的数据保存进去。由于水位线设置延迟时间为2秒,所以现在的时钟是9秒,第一个窗口也没有到关闭时间;
4. 之后又有9秒数据到来,同样进入[0,10)窗口中;
5. 12秒数据到来,判断属于[10,20)窗口,保存进去。这时产生的水位线推进到了10秒,所以[0,10)窗口应该关闭了。第一个 窗口收集到了所有的7个数据,进行处理计算后输出结果,并将窗口关闭销毁;
6. 同样的,之后的数据依次进入第二个窗口,遇到20秒的数据时会创建第三个窗口[20,30)并将数据保存进去;遇到22秒数据时,水位线到了20秒,第二个窗口触发计算,输出结果并关闭

注意!!! Flink 中窗口并不是静态准备好的,而是动态创建的——当有落在这个窗口区间范围的数据到达时,才创建对应的窗口。另外,这里我们认为到达窗口结束时间时,窗口就触发计算并关闭,事实上触发计算和窗口关闭两个行为也可以分开。

2. 窗口的分类

Flink中有很多种类的窗口,上面说的就是最简单的一种时间窗口

2.1 按照驱动类型分类

窗口本身是截取有界数据的一种方式,所以窗口最重要的信息就是怎样截取数据,以什么标准来开始和结束数据的截取,叫做窗口的驱动类型
在这里插入图片描述

2.1.1 时间窗口(Time Window)

时间窗口(Time Window)就是按照时间段去截取数据,这也是最常见的窗口。时间窗口以时间点来定义窗口的开始(start)和结束(end),所以截取出的就是某一时间段的数据。到达结束时间时,窗口不再收集数据,触发计算输出结果,并将窗口关闭销毁,也可以说基本思路就是定点发车

用结束时间减去开始时间,得到这段时间的长度,就是窗口的大小(windows size)。这里的时间可以是不同的语义,所以我们可以定义处理时间窗口和事件时间窗口。

Flink中有一个专门的类来表示时间窗口,名称叫做TimeWindow。这个类只有两个私有属性startend,这表示窗口的开始和结束的时间戳,单位为毫秒。可以通过公有的get方法调用。另外TImeWindow还提供了一个maxTimestamp()方法,用来获取窗口中能够包含数据的最大时间戳。通过代码可以看出最大时间戳就是end-1,这也代表了时间窗口的时间范围都是左闭右开的区间[start,end)

@PublicEvolving
public class TimeWindow extends Window {
    private final long start;
    private final long end;
    public TimeWindow(long start, long end) {
        this.start = start;
        this.end = end;
    }
    public long getStart() {
        return start;
    }
    public long getEnd() {
        return end;
    }
    @Override
    public long maxTimestamp() {
        return end - 1;
    }
    ....
}

2.1.2 计数窗口(CountWindow)

计数窗口是基于元素个数来截取数据,到达固定的个数时就触发计算并关闭窗口。类似于座位有限,坐满就发车,至于是否发车和时间没有任何关系。每个窗口的截取数据的个数,就是窗口的大小。

计数窗口相比时间窗口就更加简单,我们只需要指定窗口大小,就可以把数据分配到对应的窗口中,在Flink中没有相对应的类表示计数窗口,底层通过全局窗口(Global Window)来实现的。maxTimestamp返回的Long.MAX_VALUE

@PublicEvolving
public class GlobalWindow extends Window {

    private static final GlobalWindow INSTANCE = new GlobalWindow();
    private GlobalWindow() {}

    public static GlobalWindow get() {
        return INSTANCE;
    }
    @Override
    public long maxTimestamp() {
        return Long.MAX_VALUE;
    }
    @Override
    public boolean equals(Object o) {
        return this == o || !(o == null || getClass() != o.getClass());
    }
    @Override
    public int hashCode() {
        return 0;
    }
    @Override
    public String toString() {
        return "GlobalWindow";
    }
    ....
}

2.2 按照窗口分配数据的规则分类

时间窗口和计数窗口只是对窗口的一个大致划分,再具体应用时,还需要定义更加精细的规则,来控制数据应该划分到哪个窗口。不同的分配数据的方式,就可以有不同的功能应用。

根据分配数据的规则,窗口的具体实现划分为4类:滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)、会话窗口(Session Window)、以及全局窗口(Global Window)。

2.2.1 滚动窗口(Tumbling Windows)

滚动窗口有固定的大小,是一种对数据进行的均匀切片的划分方式。窗口之间没有重叠,也不会有间隔,是"均匀切片"的划分你方式。窗口之间没有重叠,也不会相隔,是首尾相接的状态。如果我们把多个窗口的创建,看作一个窗口的运动,就类似于在不停的向前翻滚一样。这是最简单的窗口形式。也因为滚动窗口是无缝衔接,所以每个数据都会被分配到一个窗口上,而且也只属于一个窗口。

滚动窗口可以基于时间定义,也可以基于数据个数定义;需要的参数只有一个:窗口的大小(Windows Size)。窗口的大小可以使一个小时一次,也可以是长度为10的数据个数。
在这里插入图片描述
如上图所示,圆点表示数据流的数据,对数据按照userID做了分区。当固定了窗口大小之后,所有的分区的窗口划分都是一致的;窗口没有重叠,每个数据只属于一个窗口。
滚动窗口应用非常广泛,它可以对每个时间段做聚合统计,很多BI分析指标都可以用它来实现。

2.2.2 滑动窗口(Sliding Windows)

滑动窗口和滚动窗口类似,滑动窗口的大小也是很固定的。区别在于窗口之间并不是首尾相连的,而是错开一定的位置。如果看作一个窗口的运动,呢么就像是向前小步滑动一样,所以滑动窗口的参数就有两个,一个是窗口大小(Windows Size),一个是滑动的步长(Windows slide),它其实就代表了窗口计算的频率。滑动的距离代表了下个窗口开始的时间间隔,而窗口大小是固定的,所以也就是两个窗口结束时间的间隔;窗口在结束时间触发计算输出结果,呢么滑动步长就代表了计算频率。例如:我们定义一个长度为1小时,滑动步长为5分钟的滑动窗口,呢么就会统计1小时内的数据,每5分钟统计一次。同样,滑动窗口也可以基于时间定义,也可以基于数据个数定义。
在这里插入图片描述
当滑动步长小于窗口大小时,滑动窗口就会出现重叠,这时候的部分数据也可能被同时分配到多个窗口中去。而具体的个数,就由窗口大小和滑动步长的比值(size/slide)来决定。如图6-18所示,滑动步长刚好是窗口大小的一半,呢么在windows1和windows2的中间部分,每个数据都会被分配到这2个窗口里。。比如窗口长度定义1个小时,滑动步长为30分钟,呢么对于8.55的数据就分别属于[8,9)和[8.30,9.30]这两个窗口;

所以,滑动窗口是固定大小窗口的更广义的一种形式;换句话说,滚动窗口也是一种特殊的滑动窗口——窗口大小等于滑动步长(size==slide)

2.2.3 会话窗口(Session Windows)

会话窗口是基于会话(session)来对数据进行分组的。这里的会话类似Web的会话session概念,不过并不代表两端的通讯过程,而是借用会话超时失效的机制来描述窗口。简单来说就是当有数据来了就开启一个窗口,如果还有数据到来就一直保持开启状态,如果在等待一段时间后没有收到数据,就认为会话失效窗口自动关闭。

与滑动窗口和滚动窗口不同,会话窗口只能基于时间来定义,而没有"会话计数窗口"的概念。类似于"会话"终止的标志就是"隔一段时间没有数据来",如果不依赖时间而改成个数,就成了"隔几个数据没有来",这是自相矛盾的说法。

会话窗口有两个重要概念,一个是这段时间的长度——Size,它表示会话的超时时间,也就是两个会话窗口之间的最小距离。还有一个是两个数据到来的时间间隔——Gap,如果新的数据到来时间小于指定的大小size,那说明还在保持会话,就属于同一个窗口;但如果gap大于size,呢么新来的数据就应该属于新的会话窗口,前一个窗口就需要关闭了。具体实现上还可以设置静态固定大小Size,也可以通过一个自定义提取器(Gap Extractor)动态提取最小间隔Gap的值

考虑到事件时间语义下的乱序流,这里又会有一些麻烦。相邻两个数据的时间间隔 gap
大于指定的 size,我们认为它们属于两个会话窗口,前一个窗口就关闭;可在数据乱序的情况
下,可能会有迟到数据,它的时间戳刚好是在之前的两个数据之间的。这样一来,之前我们判
断的间隔中就不是“一直没有数据”,而缩小后的间隔有可能会比 size 还要小——这代表三个
数据本来应该属于同一个会话窗口。所以在 Flink 底层,对会话窗口的处理会比较特殊:每来一个新的数据,都会创建一个新的会话窗口;然后判断已有窗口之间的距离,如果小于给定的 size,就对它们进行合并(merge)操作。在 Window 算子中,对会话窗口会有单独的处理逻辑。
在这里插入图片描述
会话窗口和之前两种窗口不同,没有固定长度,起始和结束时间也不确定,各个分区之间窗口也是没有联系的。如图 6-19 所示,会话窗口之间一定是不会重叠的,而且会留有至少为 size 的间隔(session gap)。

2.2.4 全局窗口(Global Windows)

还有一类比较通用的窗口,就是“全局窗口”。这种窗口全局有效,会把相同 key 的所有数据都分配到同一个窗口中;说直白一点,就跟没分窗口一样。无界流的数据永无止尽,所以这种窗口也没有结束的时候,默认是不会做触发计算的。如果希望它能对数据进行计算处理,还需要自定义“触发器”(Trigger)。
在这里插入图片描述
如图 6-20 所示,可以看到,全局窗口没有结束的时间点,所以一般在希望做更加灵活的窗口处理时自定义使用。Flink 中的计数窗口(Count Window),底层就是用全局窗口实现的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1473645.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【hashset】【hash查找元素O(1 )时间复杂度】Leetcode 128. 最长连续序列

【hashset】【hash查找元素O(1 )时间复杂度】Leetcode 128. 最长连续序列 解法1 hashmap解法2 不满足题设 排序遍历 ---------------🎈🎈题目链接🎈🎈------------------- 解法1 hashmap 核心思想 利用了ha…

Vue3的8大生命周期

查看本专栏目录 关于作者 还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas&#x…

Vue.js+SpringBoot开发快递管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

windows 连接 Ubuntu 失败 -- samba服务

1. windows10连接ubuntu的时候,提示不允许一个用户使用一个以上用户名与服务器或共享资源的多重连接,中断与此服务器或共享资源的所有连接,然后再试一次 2. 换一台同事的电脑却又可以连上,我之前一直能用的,隔一段时间…

【 C++ 】bitset位图的模拟实现

位图概念 曾经有这样一个面试题,如果给你40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。【腾讯】方法如下: 遍历,时间复杂度O(N)。排序(O(NlogN)),利用二…

文献速递:深度学习--深度学习方法用于帕金森病的脑电图诊断

文献速递:深度学习–深度学习方法用于帕金森病的脑电图诊断 01 文献速递介绍 人类大脑在出生时含有最多的神经细胞,也称为神经元。这些神经细胞无法像我们身体的其他细胞那样自我修复。随着年龄的增长,神经元逐渐死亡,因此变得…

袁庭新ES系列12节 | Elasticsearch高级查询操作

前言 上篇文章讲了关于Elasticsearch的基本查询操作。接下来袁老师为大家带来Elasticsearch高级查询部分相关的内容。Elasticsearch是基于JSON提供完整的查询DSL(Domain Specific Language:领域特定语言)来定义查询。因此,我们有…

Python实现自动检测设备连通性并发送告警到企业微信

背景:门禁机器使用的WiFi连接,因为某些原因会不定期自动断开连接,需要人工及时干预,以免影响门禁数据同步,故写此脚本,定时检测门禁网络联通性。 #首次使用要安装tcping模块 pip install tcpingfrom tcpin…

幻兽帕鲁服务器哪家便宜?阿里云腾讯云京东云华为云对比

幻兽帕鲁服务器哪家便宜?阿里云腾讯云京东云华为云对比,阿里云更便宜,26元1个月。游戏服务器租用多少钱一年?1个月游戏服务器费用多少?阿里云游戏服务器26元1个月、腾讯云游戏服务器32元,华为云26元&#x…

Android WebView访问网页+自动播放视频+自动全屏+切换横屏

一、引言 近期,我发现电视家、火星直播等在线看电视直播的软件都已倒闭,而我奶奶也再无法通过这些平台看电视了。她已六十多岁,快七十岁啦。这些平台的倒下对我来说其实没有多大的影响,但是对于文化不多的她而言,生活中…

常见需求:CSS 实现弧形卡片的 3 种方式

公众号:程序员白特,欢迎一起交流学习~ 原文作者:前端侦探 在平时开发中,有时候会碰到下面这种“弧形”样式,主要分为“内凹”和“外凸”两种类型,如下 该如何实现呢?或者想一下,有哪…

用 Pyinstaller 模块将 Python 程序打包成 exe 文件(全网最全面最详细,万字详述)

目录 一、打包前置知识 1.1 什么是 exe 可执行文件? 1.2 为什么要将 Python 程序打包为 exe 可执行文件? 1.3 为什么 Python 程序不能直接运行呢? 1.4 我们用什么来打包 Python 文件呢? 1.5 打包有哪几种分类呢&#xff1f…

Spring-Cloud-Gateway集成Sentinel限流

1&#xff09;gateway添加sentinel相关依赖 <spring-cloud.version>2021.0.1</spring-cloud.version> <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version><dependencies><!--gateway--><dependency><gro…

多模态表征—CLIP及中文版Chinese-CLIP:理论讲解、代码微调与论文阅读

我之前一直在使用CLIP/Chinese-CLIP&#xff0c;但并未进行过系统的疏导。这次正好可以详细解释一下。相比于CLIP模型&#xff0c;Chinese-CLIP更适合我们的应用和微调&#xff0c;因为原始的CLIP模型只支持英文&#xff0c;对于我们的中文应用来说不够友好。Chinese-CLIP很好地…

为什么要智慧公厕?智慧公厕是做什么的

在现代城市信息化建设进程中&#xff0c;公共卫生设施的建设与管理一直备受关注。而随着科技的迅速发展&#xff0c;智慧公厕作为一种新型的信息化公共设施&#xff0c;正逐渐走进人们的视野。本文以智慧智慧源头厂家广州中期科技有限公司&#xff0c;大量精品案例现场实景&…

【重要公告】BSV区块链协会宣布将启动多项动态安全增强措施

​​发表时间&#xff1a;2024年2月16日 2024年2月16日&#xff0c;瑞士楚格 - BSV区块链协议的管理机构BSV区块链协会&#xff08;以下简称“BSV协会”&#xff09;宣布对其运营模式实施全新的安全架构&#xff0c;其中包括引入网络访问规则和数字资产找回协议&#xff0c;以及…

【非递归版】归并排序算法(2)

目录 MergeSortNonR归并排序 非递归&归并排序VS快速排序 整体思想 图解分析​ 代码实现 时间复杂度 归并排序在硬盘上的应用&#xff08;外排序&#xff09; MergeSortNonR归并排序 前面的快速排序的非递归实现&#xff0c;我们借助栈实现。这里我们能否也借助栈去…

浅谈Unity内存管理

浅谈Unity内存管理 前言 很早之前记录的Unity内存相关的知识点&#xff0c;在此补充到博客上来。有什么不对的地方欢迎指正探讨。 内存概念 虚拟内存&#xff08;Virtual Memory&#xff09; 众所周知&#xff0c;物理内存就是插在计算机主板内存槽上的实际物理内存。 虚拟…

SAP中分包后续调整应用实例二(调减)

之前己写过一篇介绍过分包后续调整功能MB04的基本应用。当时的场景是某个原材料由于各方面原因&#xff08;比如没有维护到BOM中&#xff09;&#xff0c;在委外加工模式成品收货后&#xff0c;并没有消耗或少消耗&#xff0c;这时可以用该事务功能来补充消耗。在生产报工中的M…

redis八股

文章目录 数据类型字符串实现使用场景 List 列表实现使用场景 Hash 哈希实现使用场景 Set 集合实现使用场景 ZSet 有序集合实现使用场景 BitMap实现使用场景 Stream使用场景pubsub为什么不能作为消息队列 数据结构机制SDS 简单动态字符串压缩列表哈希表整数集合跳表quicklistli…