Flink窗口核心概念-有KEY窗口和无KEY窗口

Flink窗口核心概念-有KEY窗口和无KEY窗口,第1张

Flink窗口核心概念-有KEY窗口和无KEY窗口

文章目录

(一)WIndow与WindowAll区别(二)有KEY 窗口和无KEY窗口

(1)有KEY窗口(2)无KEY窗口 (三)有KEY窗口 无KEY窗口验证

(1)有KEY窗口执行结果示例(2)KeyBy-window-apply-sink算子链解释(3)无KEY窗口执行结果示例

(一)WIndow与WindowAll区别

在前边的WindowAPI调用时,我们发现不仅有Window(),还有WindowAll(),那这两者之间有什么区别呢?

Windows是处理无限流的核心。Windows将流分成有限大小的“存储桶”,我们可以在其上应用计算。

窗口式Flink程序的一般结构如下所示,分为键控流数据与非键控流数据,他们的区别正如您所看到的,唯一的区别是原始流是否进行了keyBy()

在上面,方括号([…])中的命令是可选的。这表明Flink允许您以多种不同方式自定义窗口逻辑,从而使其最适合您的业务需求。

总结:使用了KeyBy()算子后,数据流就会变为键控流;键控流应该使用window方法,未使用keyby()的流(非键控流),应该调用windowAll方法

(二)有KEY 窗口和无KEY窗口

键控流调用window() 或者直接使用timeWindow()、countWindow() 都是使用的有KEY窗口

(1)有KEY窗口

自定义有KEY窗口Function继承的的是RichWindowFunction

有key 窗口,作用在键控流基础之上,持有相同key数据会进入同一个窗口。有KEY窗口可根据并行度设置开启多个窗口,引用同一键的所有元素始终都将被发送到同一并行任务执行。(窗口计算会由多个subtask(根据并行度)执行,具有相同类型的key会进入同一个subtask执行。)

注意点:有KEY窗口会根据并行度开启对应数量个窗口,比如设置了并行度为4,那么只会开启4个窗口

具有相同key的数据会进入同一个subtask执行,但不代表一个subTask永远只会处理一个Key的数据,因为可能根据KeyBy后存在超出并行度数量的KEY, 那么超出的KEY仍会根据一定规则选择一个subTask执行,且以后一直由那一个subtask执行,只是说一个SubTask在处理当前KEY的时候会阻塞,当一个KEY的数据处理完了后,才会处理另一个KEY数据

(2)无KEY窗口

自定义无KEY窗口Function继承的的是RichAllWindowFunction

无KEY窗口,作用在非键控流基础之上,您的原始流将不会拆分为多个逻辑流,并且所有窗口逻辑将由单个任务(即并行度为只会为1)执行。

(三)有KEY窗口 无KEY窗口验证 (1)有KEY窗口执行结果示例

由于我设置了并行度为4,故此打开了四个窗口,且当前Job中,每个算子的并行度最多为4

打印说明:

打印语句前的 1 、3、4 可以视作为当前输出时(sink时)并行度线程编号,这个是从我们的sink输出方式print()打印出来的,1 可视为subtask1、3 可视为subtask3…

我们可以看到,subtask1输出了vehicleId=6的数据,后边又输出了一个vehicleId=4的数据,接着又输出了vehicleId=6的两条数据

subtask3接连输出了5条vehicleId=1的数据,然后下边还输出了一条vehicleId=4的数据…

比如 vehicleId=1、 vehicleId=0、 始终会进入subTask3执行计算逻辑; vehicleId=6 始终会进入subTask1执行计算逻辑

这就说明了,窗口计算会由多个subtask(根据并行度)执行,具有相同类型的key会进入同一个subtask执行。


(2)KeyBy-window-apply-sink算子链解释

哎!我就知道,直接看我这篇文章的朋友可能有点疑惑了!这明明是SInk打印的线程号,你咋证明Window和Sink 是用的一个线程呢?

答:因为算子链的机制,让KeyBy-window-apply-sink 组成了算子链(合为一个算子),组成后,就可以理解为KeyBy-window-apply-sink 是串行 *** 作的了,那么既然是串行 *** 作,自然window是啥线程执行,sink就是啥线程执行了呀!

详情请戳:Flink JobManger、TaskManger、TaskSlots、Client作用

详情请戳:Flink TaskSlot与并行度


请问各位小伙伴,当前这个Job会启动几个Task 几个subTask呢?

答:共2个task 共5个subTask; 一个task 是source(并行度为1 1个subtask),一个task是KeyBy-window-apply-sink (四个并行度 则有4个subtask)

那明明我env设置并行度为4,为啥source还是一个呢?因为SourceFunction只支持单并行度,即使你env设置4,也不会生效!

详情请戳:Flink程序加载数据源(3)自定义数据源(1)

直接上图为证!

可以看到,上方一共两个大Task 一个五个subtask,因为一个并行度中KeyBy-window-apply-sink 是串行 *** 作,则window中的线程与sink线程为同一个

(3)无KEY窗口执行结果示例

上图示例可以发现,虽然我们的env设置了并行度为4,但窗口仍只是打开了一个,这就验证了无KEY窗口并行度只会为1;但是由sink的subTask数量完全受并行度影响,故此,sink仍会有四个线程同时执行;且没有同一个Key数据会进入同一线程限制,no-key-window计算后结果由哪一个sink-subTask执行,完全随机!

例如上图,vehicleId=2的数据,一开始被sink-subTask2执行,下一次又被sink-subTask1执行

问题又来了!按照此代码,我们当前Job会有几个task 几个subTask呢?

答:当前job执行时会有3个task,6个subTask;3个task为soure、no-key-window、sink ;6个subTask分别为 source 一个、no-key-window一个、sink四个

点击详情页查看

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5700130.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存