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

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;}@Overridepublic 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;}@Overridepublic long maxTimestamp() {return Long.MAX_VALUE;}@Overridepublic boolean equals(Object o) {return this == o || !(o == null || getClass() != o.getClass());}@Overridepublic int hashCode() {return 0;}@Overridepublic 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.mzph.cn/news/704758.shtml

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

相关文章

c语言-day1(ubuntu操作系统及指令)

1:思维导图 2: (1): (2) (3) (4) (5)

通过盲注脚本复习sqllabs第46关 order by 注入

sql-lab-46 order by 注入是指其后面的参数是可控的, order by 不同于我们在 where 后的注入点,不能使用 union 等注入,其后可以跟接 报错注入 或者 时间盲注。 数字型order by注入时,语句order by2 and 12,和order by2 and 11显示的结果一…

前端框架的CSS模块化(CSS Modules)

创作纪念日之际,来给大家分享一篇文章吧 聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们…

Vue前端对请假模块——请假开始时间和请假结束时间的校验处理

开发背景:Vueelement组件开发 业务需求:用户提交请假申请单,请假申请的业务逻辑处理 实现:用户选择开始时间需要大于本地时间,不得大于请假结束时间,请假时长根据每日工作时间实现累加计算 页面布局 在前…

二进制部署k8s之网络部分

1 CNI 网络组件 1.1 K8S的三种接口 CRI 容器运行时接口 docker containerd podman cri-o CNI 容器网络接口 flannel calico cilium CSI 容器存储接口 nfs ceph gfs oss s3 minio 1.2 K8S的三种网络 节点网络 nodeIP 物理网卡的IP实现节点间的通信 Pod网络 podIP Pod与Po…

视频和音频使用ffmpeg进行合并和分离(MP4)

1.下载ffmpeg 官网地址:https://ffmpeg.org/download.html 2.配置环境变量 此电脑右键点击 属性 - 高级系统配置 -高级 -环境变量 - 系统变量 path 新增 文件的bin路径 3.验证配置成功 ffmpeg -version 返回版本信息说明配置成功4.执行合并 ffmpeg -i 武家坡20…

GOOGLE Colab Pro会员订阅开通购买付费充值教程

一、简介 colab由谷歌团队开发,用于机器学习、数据分析,教育等目的,他的会员也非常的昂贵,最基本的套餐要10美金,最高要50美金一个月,如何省钱,往下看。 一般来说土区的价格比较便宜&#xff0…

Day02:Web架构前后端分离站Docker容器站集成软件站建站分配

目录 常规化站点部署 站库分离 前后端分离 集成软件搭建Web应用 Docker容器搭建Web应用 建立分配站 静态 与 伪静态 总结 章节知识点: 应用架构:Web/APP/云应用/三方服务/负载均衡等 安全产品:CDN/WAF/IDS/IPS/蜜罐/防火墙/杀毒等 渗…

怎么把pdf转换成word?

怎么把pdf转换成word?Pdf和word在电脑上的使用非常广泛,pdf和word分别是由 Adobe和Microsoft 分别开发的电脑文件格式。PDF 文件可以在不同操作系统和设备上保持一致的显示效果,无论是在 Windows、Mac 还是移动设备上查看,都能保持…

配置多个后端 API 代理

在开发 React 应用时,通常会涉及到与后端 API 的交互。而在开发过程中,我们经常需要在开发环境中使用代理来解决跨域请求的问题。Create React App 提供了一种简单的方式来配置代理,即通过创建一个名为 setupProxy.js 的文件来配置代理规则。…

《数据治理简易速速上手小册》第4章 数据安全与合规性(2024 最新版)

文章目录 4.1 数据安全的基本原则4.1.1 基础知识4.1.2 重点案例:在线零售商的数据加密4.1.3 拓展案例 1:医疗机构的访问控制4.1.4 拓展案例 2:金融服务提供商的数据备份和恢复 4.2 遵循数据合规性的策略4.2.1 基础知识4.2.2 重点案例&#xf…

PHPStudy无法解析php(7.3.4)文件

#告诉服务器,对于以.fcgi、.php或.phtml为后缀的请求,应该使用FPM进行处理。 AddHandler fcgid-script .fcgi .php .phtml #设置了全局默认使用的PHP版本路径 FcgidInitialEnv PHPRC "D:/phpstudy_pro/Extensions/php/php7.3.4nts" #告诉服务器…

Django学习笔记-ModelForm使用(完全依赖)

1.创建模型 ,code,name,sex,entrydate 2.模型映射 python manage.py makemigrations myapp01,python manage.py migrate 3.创建模型表单,继承forms.ModelForm,Meta:元数据,models需引入,fields填写引用的模型变量 4.创建testModelForm.html,添加urls 5.views编写testmodelfo…

simple-pytest 框架使用指南

simple-pytest 框架使用指南 一、框架介绍简介框架理念:框架地址 二、实现功能三、目录结构四、依赖库五、启动方式六、使用教程1、快速开始1.1、创建用例:1.2、生成py文件1.3、运行脚本1.3.1 单个脚本运行1.3.2 全部运行 1.4 报告查看 2、功能介绍2.1、…

设计模式(八)外观模式

相关文章设计模式系列 1.外观模式简介 外观模式介绍 当我们开发Android的时候,无论是做SDK还是封装API,我们大多都会用到外观模式,它通过一个外观类使得整个系统的结构只有一个统一的高层接口,这样能降低用户的使用成本。 外观…

面试redis篇-10Redis集群方案-主从复制

在Redis中提供的集群方案总共有三种: 主从复制哨兵模式分片集群主从复制 单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。 主从数据同步原理 Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每…

Java SpringBoot 创建项目工程输出 Hello World

Java SpringBoot 创建项目工程输出 Hello World 1、新建项目 2、创建 controller 3、编写 Hello World 代码 package com.zhong.demo01.controller;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.Res…

本地项目如何上传到gitee

文章目录 一、在gitee上新建远程仓库二、初始化本地仓库三、执行git命令上传代码 一、在gitee上新建远程仓库 仓库名称必填,路径自动跟仓库名称保持一致 解释说明: 仓库名称:必填,每个仓库都需要有一个名称,同一个码…

kubectl 命令行管理K8S

目录 陈述式资源管理方式 介绍 命令 项目的生命周期 创建 kubectl create命令 发布 kubectl expose命令 更新 kubectl set 回滚 kubectl rollout 删除 kubectl delete 陈述式资源管理方式 介绍 1.kubernetes 集群管理集群资源的唯一入口是通过相应的方法…

量子前沿:美国计算社区联盟CCC发布量子计算进展最新研报!

内容来源:量子前哨(ID:Qforepost) 编辑丨慕一 编译/排版丨沛贤 深度好文:1800字丨12分钟阅读 近日,美国计算社区联盟 (CCC) 发布了过去五年量子计算进展的最新报告。CCC还分享了美国东北大学库里计算机科…