00:00
好,那接下来我们就来看一看在flink的程序里边到底怎么样调用window API去实现一个窗口操作。那这里边要给大家主要说的就是flink当中。进行窗口操作的时候呢,它的主要其实是有两步操作的。啊,那大家可能会想到你窗口开窗嘛,那其实整体来讲不就是应该有一个点window,类似于这样的一个开窗操作吗?啊,确实是的啊,前面首先我们要做的第一步操作就是直接点window,这一步操作叫一个窗口分配器。那么除了这一步操作之外呢,后边还必须在基于这个窗口再定义一个啊,我要针对这个窗口做什么计算,后边的这个叫做窗口函数,所以完整的代码里面的实现大家看一下啊,是这样的一个过程,首先我们有一个基本的data stream,然后接下来啊,比方说啊,你前面可以做一些操作,Map filter,对吧,做一些基本的转换,然后接下来呢,注意如果我要想直接掉点window方法的话。
01:05
必须先做一个K败。然后再去调window操作。然后做完window操作之后,后边还必须再去跟上一个类似于聚合的,大家看这是明对吧,类似于聚合的一步窗口操作,我们把后边这个叫做窗口函数,所以前边的这一步窗口分配器和后边窗口函数缺一不可,这就是完整的一个窗口操作啊,那接下来我们首先先给大家看这个窗口分配器啊,窗口分配器简单来讲的话就是点运动。啊,这里边大家注意就是说必须要先KBY之后才能掉这个点window方法,那我们看到这里边的这个事例里边其实是没有那么麻烦啊,直接上来之后就是一个点time window,它其实就是一个点window的简写形式,说明我这里边你不用管别的了,它本身就是一个时间窗口,对吧?啊,然后时间窗口里边,你看这里边给了一个参数time.SECOND15,大家知道这是啥意思吗?
02:10
对,大家想这是15秒的意思对吧?给了一个15秒长度,只给一个参数,大家想这应该是个什么时间窗口啊,对,滚动时间窗口,所以就是15秒的滚动时间窗口对吧?与之对应还有一个点抗图运动方法,就可以直接去定义技术窗口,对,所以接下来我们在代码里边给大家试一试啊,看看这个东西到底怎么用,那同样我们还是在当前Java下边去创建一个class啊,那当前这个我们带上包名com,点艾特硅谷,点API test,呃,接下来我们这个是window相关的操作,对吧?哎,那首先。我定义一个类叫做window test1呃,当前我们首先来给大家测一测这个,呃,就是time window吧。
03:08
然后前面的这个整体流程啊,还是一样,我先把这个写出来。主方法,呃,这里边我要去throw一个exception下边stream execution environment,还是获取当前的执行环境,定义成EV啊,然后为了方便我们打印输出的,按照顺序输出,还是全局并行度射成一对吧啊,然后后面整个过程当中还是啊读取数据,然后去转换成相对应的这个po类型,我还是把这个直接copy过来。好,直接引入。然后最后。大家不要忘记这个架构里边还应该有一个execute直接执行的这个过程,对吧,先把这个都都写出来,然后我们看。好,这里边好像多了一个多了一个这个画括号啊,好,这样的话整个架构就没有问题了,那接下来我们其实要测试这个窗口测试对吧,我们这里面只是先看一看这个开窗到底是怎么样去开开窗,所以这里边我应该给大家写的是开窗测试啊。
04:25
我这里其实就是直接基于这个data stream,然后大家看如果我要直接调点window的话,能直接调吗?没有点window方法,但是有一个window or方法,哎,这是要跟大家说一句的,就是直接基于data stream,可以调一个对应的一个开窗操作,这个开窗操作不叫window,而是叫window or,这个window or大家注意一下啊,它上面这个源码里边是有注释的,这个WINDOW2会把这个所有的数据放到哪里去呢?
05:00
啊,大家注意啊,就这里边所有的这个数据都会被放到大家看,就是这个操作,它这个本身啊,它是一个non parallel,所有的这个数据都会被传递到同一个。下游算子的这个instance里面去,实例里面去,这是什么意思呢?对,大家想是不是接下来这就是一个global操作啊,类似于之前我们说的那个数据传输的时候,里边有一个global的做法,对吧?所以所谓的window or,大家想到它就是是不是要把所有数据都放在一个窗口里边去做统计啊,啊那所以那当然我我们接下来是不是相当于就是一个分区啊,要不然你怎么样,所有都统计在一起吗?你要分区的话,那最后不是还得汇总吗?啊,所以它其实就有一个global操作。这个在官网里边有说法,就是建议大家如果不是非常必要的话,尽量不要直接上来用window or,因为它相当于是不是相当于并行度都变成一了呀,对吧,你本身这个相当于资源就都没利用起来啊啊所以一般常规情况下,我们这里边不是直接去做这个WINDOW2的啊,大家也看到了,另外它也有简写形式,是不是time window2和com控WINDOW2啊,对吧,就基于这个data stream直接开时间窗口和技术窗口,那所以这里边如果我们不这么做的话,那就先KBY啊对KBY一个,比方说ID对吧,按照ID做一个分组,然后。
06:28
之前我们说得到的这个k stream是可以做滚动聚合了,可以some,可以max me,可以reduce,对吧?哎,那现在我们不是做这些操作,我是要去,诶大家看现在是不是直接有window操作啊,当然它也也可以window or,那是因为k stream是不是继橙字data stream呀,对吧?这里我当然不要,你既然已经KY了嘛,然后你又把它global传到同一个分区,那也没必要,对吧,我现在就是按不同的这个K,不同的这个分组啊,分组的这个对应的sensor传感器去做一个统计,所以我就直接window就可以了,这是一般化的这个写法。
07:04
哎,那大家看一下这个window里面要传一个什么东西。Window里边要传的是一个。Window a signer对吧?哎,这个window a signer,这就是我们所说的窗口分配器,这个window sign本身是一个抽象类,那么它有哪些对应的具体实现呢?大家看就在这里边对吧,然后就是这里边有这个啊,这有各种各样花式的啊,前面一堆这个前缀,这个大家可以先不用考虑的那么多啊,比方说session Windows,有session window对吧?然后有这个啊,Even time session Windows啊,还有global Windows,大家知道这个window,你那个time window2是不是应该就是global window啊,对吧?所以这个其实就是类似这样的一个东西啊,然后还有这个,呃,这还是session window啊,下面还有sliding even time Windows对吧?Sliding processing time window,这至于这个even time和processing time,这又是什么呢?
08:02
这是后面要给大家讲到的时间与意义的概念啊,现在大家可以先不做太多的呃处理,我们就认为它就是一个就是一个时间就可以了,对吧,基于时间的一个滑动窗口,另外还有这个滚动窗口,那就是tumbling even time Windows tumbling processing time window对吧?啊所以之前我给大家说这个英文名还要稍微记一下啊,至少记住这个前几个字母是怎么写的啊啊,那这里边把这个要要直接这么定义的话,那那我这里应该怎么写。就是在这里边,你想要直接window里边去传一个这个这个参数的话怎么写啊。哎,那有同学可能想到,那我是直接去new一个这个t tumbling even time Windows或者是其他的这个这个Windows吗?是直接这么去写吗?那大家来看一眼啊。看它的构造方法是protected对吧,一看这种方式,那就说明不能这么写得怎么写啊对,下面是不是肯定得有其他的,比方说他有其他的内部类对吧?或者是有其他的一些方法去给他调用自己的这个保护受保护的这个构造方法对吧?这里边它能够返回自己的这个类型,调用它的构造方法的是一个of方法。
09:18
大家看这个of是不是返回了一个top even time Windows啊,所以这里边我要调的其实是什么呢?因为我上面这个啊。本身那个of大家看到了,它本身是一个。本身是一个static静态方法对不对,所以是不是我直接调就完事了啊,所以接下来啊,不要去new,而是tumbling even time Windows啊,或者啊,或者大家看还有另外一个一个一个方式是processing time Windows,对吧?啊,就是tumbling processing time Windows,这两种都都是一个滚动时间窗口啊,然后直接点哦,里边传什么参数呢?当然就是当前,哎窗口的大小嘛,对吧,Time点大家看点,然后给定一个单位,然后给一个长整形的数值,对吧?比方说我这里边要一个15秒钟的滚动窗口,是不是直接这么定义就可以了,哎,这就是这个time window开窗的这个做法。
10:18
那大家可能会发现这种方式确实是有点儿,呃,有点麻烦是吧,有点笨啊,那那假如说我接下来就是想要简单去写的话,可以怎么写呢?这个方式刚才大家也看到了,直接是不是可以time window啊,Time window就非常的简单粗暴,这里边直接就是time.SECOND15就完事了。啊,那有同学可能会说,那不对呀,你像下面的这个window,这是它明确的告诉我们,这里边是一个滚动的时间窗口,对吧?那你这里只说是一个时间窗口,我怎么知道是滚动还是滑动呢?哎,对,大家看到这个time window里边是不是它有两种不同的这个传参方式啊,一个是传一个time,另外一个是传两个time,那大家知道怎么区别吗?传一个time,这里边调用的是什么?哎,大家看。
11:16
底层是不是就是这个呀,Return一个window,然后怎么样,Ting processing time windows.off对吧?然后这里边分别调哪个呢?这是要看当前的这个时间特性到底是什么对吧?就是时间语义到底是什么啊,来来判断我当前调的是哪个,到底是processing time window还是even time window,这个后续我们再说,大家只要知道这里边底层掉的是这个点of方法就可以了。这是只有一个参数的情况,那如果要有两个参数呢?大家看第二个参数是不是就变成了一个slide呀,Slide就是滑动不长,里边调的是不是就是slideding processing time windows.of对不对?哎,这就是一个滑动的哎,时间窗口对吧?然后这里边的of是不是也有两个参数啊,哎,这就是这样的一个处理的过程啊。
12:07
呃,这里需要给大家多说一句的是,呃,有同学可能想到,那如果要这么说的话,那session window怎么来做呢?Session window是不是这里边直接就有一个,我把这个先注掉啊。是不是这里就直接会有一个点session window呢?大家看没有对吧,没有这样的简写方式,所以如果是session window的话,那就必须直接对调底层的点,呃window对吧?然后这里边你可以看一下啊,有没有对应的这个session window,之前我们在这其实已经看到了啊。哎,它是先写那个even time对吧,或者是processing time啊,是这样的啊,所以是我可以把这个写出来window对吧,我可以调这个对吧,Even time session Windows processing time session Windows,然后后边会有一个with GAP方法,大家看这里边一样,就是它的这个构造方法啊,也是protected,然后呢,里边是不是这个with GAP这个方法是可以返回一个调它的这个构造方法,返回对应的这个类型啊。
13:13
实例对吧,啊,当前的这个对象实例是可以这样返回的,然后里边传进来的,其实就是它的那个。就是间隔时间对不对,诶这里边就是比方说我间隔一分钟的一个间隔时间,构造这样的一个会话窗口,这也是可以的,对吧。啊,那除了这种调用方式之外,另外还有就是技术窗口的话,是不是可以直接count window啊,Count window里边的传参方式。再看一眼,大家看这边就是也是有两种不同的,大家看这count window啊,两种不同的传参方式,传一个参数,一个长整形,这就表示滚动技术窗口,对,那后面如果传两个参数的话,那就是上面啊。这是不是就是诶去哪了。
14:02
看一眼后面那个这个对吧,传两个参数,这就是滑动技术窗口,哎,那底层大家看一下它底层其实是什么呢。大家注意啊,这个一般我们就不要再写成那种复杂的形式了,之前我们还可以把这个时间窗口直接写成这个复杂形式,对吧,这里面滚动窗口的话,你比方说滑动,呃,滑动的这个技术窗口啊,技术窗口,技术窗口的话,你最好就不要那么复杂的写了,因为复杂写它底层实现其实是。Global windows.create create对吧,所以这里面就涉及到了所谓的这个,呃,窗口分配器啊,到底有哪几类,所以大家其实看到了,现在我们接触到的这个窗口分配器有哪几类呢?主要就是这么四类对吧?首先滚动窗口分配器TUM0WINDOWS,另外是滑动窗口分配器sledding Windows,还有绘画窗口分配器session Windows,对吧?这是不是都是在这个window里边可以直接传的这些方法呀?另外还有一个叫对全局global Windows,那大家可能会想到global Windows,这不是应该那个global之后应该是传到同一个分区里面去了吗?那怎么这里面又说它是一个技术窗口,还是可以分别去统计呢?
15:23
那是因为后边大家看它还可以去自定义evi和trigger,这是什么东西呢?哎,这就是对它的移除器和触发器,就是表示我确定这个窗口哪些数据要,哪些数据不要,这个叫移除器。那另外这个trigger呢,就是我这个窗口到底什么时候截止,什么时候统计这个窗口里面到底是有哪些数,对吧?啊就是什么时候关闭,这是这个trigger去控制的。这就是当前这个count window啊,它的一个底层实现,所以一般情况我们如果要用的话,不会去调这个底层方法,直接这么写,这就一目了然对吧?哎,所以一般就是直接这么去写出来就就可以了啊。
16:09
这是关于我们这个开窗测试的一个一个过程啊,我把这个time window可以放开啊,那么大家也可以看到具体来使用的时候,这个window sign有下边这四类啊,滚动窗口,滑动窗口,会话窗口和全局窗口,而我们一般情况前面讲的五类窗口啊。五大类窗口对吧?具体来调用这个window方法去创建的时候怎么创建呢?哎,一般就是这样,滚动时间窗口是不是直接点time给一个参数就可以了,然后滑动时间窗口是不是给两个参数就可以了,后面这个会话窗口,那这个没有简单的简写形式,是不是必须点window,然后里边给一个session window的那个窗口分配器啊啊,这里边是点with GAP啊用这种方式去创建。而后边的这个count window呢,啊,大家也是那那个的话就尽量不就不要用那个底层的方式,底层方式那个太麻烦了,对吧,我这里边就直接用简写形式点count window,然后给一个参数就是滚动技术窗口,两个参数就是滑动技术窗口,这就是所谓的窗口分配器。
我来说两句