00:00
然后接下来我们就要讲这个window的API了,Window的API呢,其实也很简单,呃,Spark里边也有window,那大家想一想,Spark里边的window是什么window啊?啊对,其实Spark里边的window就是滑动window对不对,滑动窗口啊,那我们也说了嘛,这个就是呃,滚动窗口可以认为是特殊的滑动窗口,对吧?啊,那会画窗口,这个可能应用的场景比较少,所以我们一般情况啊,不考虑也是有可能的,好,那接下来我们说这个window API。那大家可能知道最简单的操作是什么呢?怎么样去创建开一个窗口呢?那最简单的方法就是,就是用一个这个窗口的分配器,就是调用window方法,就直接在我们的那个流上面,直接点window来定义一个窗口,然后呢,在后边继续就可以做一些聚合或者其他的一些处理操作,要基于它再做操作,这里大家要注意一下啊,就是点window这个方法必须要在KBY之后才能用。
01:10
也就是说。窗口分配器。这个window。是本就是window方法是只能应用在kid stream上面的,那大家可能想到那一般的data stream可以去开窗吗?开window吗?可以。那种开窗的方法叫WINDOW2,就是点WINDOW2啊,那大家可能想到它们俩有什么区别呢?可以跟大家说几乎没什么区别,几乎都一样,所不同的就是这个window是基于k stream,那大家会想到是不是按照不同的key就做了分区啊,对吧,然后就可以有这种并行度的这种设置和调节啊,呃,而那个如果是WINDOW2的话,那就是。所有的数据都在一个分区上,对吧?啊,都是统一去处理的,这种方式一般不是特别的推荐,所以说就是可能呃,一般情况也不会直接去用啊,大大家就是大概知道一下就可以了,好,所以这是这个window和WINDOW2啊,我们现在就是以这个window作为例子,那大家看一下这个window的使用,另外给大家说一句,就是flink呢,还提供了更简单的一个调用,因为大家知道window不是分两大类,有time window,有count window吗?那你这里边直接点window里边是不是还可指定这到底是time还是count啊,它有一个更方便的方式,就是可以直接点time window。
02:38
和点抗图运动对吧?啊这个就非常简单了,所以大家看一个例子把这个代码啊,看一个例子前面是data stream对吧,一个data stream啊就做map,然后大家看直接点KBY,就是先做了这个,呃,这个分组对吧,分区的这个操作,然后接下来就可以直接点太AG window,那大家会看到type window里边直接传一个数,这表示什么呢?这15秒对吧?Time角SECOND15 15秒,这表示什么呢?这表示就只有一个参数哦,那家会想到这应该是个什么,什么探步运动啊,滚动的对一个参数嘛,那是不是你滑动至少是不是得两个参数啊对,所以大家一看这个就能知道它是一个滚动的窗口啊,然后后面大家看就可以直接点reduce做这个聚合操作了啊,就是使用其实还是很方便的啊呃,我们先往后讲,后面再给大家代码里边去实现,然后大家看看这个效果怎么样。
03:39
呃,然后这里边要给大家讲一讲这个window方法啊,Window方法它其实接受的参数输入参数,这里面这个参数啊,是一个window a ser。就这里边其实是一个window center,大家都会想到这应该是一个类了,对吧?呃,或者是一个接口啊,那么这个东西它是干什么用的。
04:00
为什么它叫窗口分配器啊ser呢?就是这步操作,点window这个操作传入这个分配器之后,其实就是要定义好每一条输入的数据分发到哪个窗口去,也就是说定义出来我到底是什么样的窗口,对不对?哎,你是滚动的还是滑动的,你是多大的对吧?滑动波长是多少?定义好这个之后,我就知道每一条数据应该分发到哪个窗口里面去了,所以这是这一步窗口分配器做的事情。哎,那大家就会想到那窗口操作没完啊,对吧,他只知道数据分到哪个窗口里面去,所以后边是不是一定还要再跟上一个类似于这样的一个聚合操作。这个才是把窗口真正做统计做计算对不对,哎,所以大家注意啊,这就是窗口操作,其实是分成两步,至少分成两步的。这两步都是必要的,就一个是前面的点window,你type window也好,对吧,或者count window也好,这个是定义一个窗口分配器,另外还要做一个聚合操作,或者说其他的一些处理操作,这个是所谓的window function,就是window的处理函数,对吧?
05:17
好,那接下来这里我们先给大家讲这个分配器啊S呃,它的主要作用就是说出分发数据到证确窗口,Flink里边呢,给我们提供了一些通用的window signer啊,大家可以看到啊,通用的window sign有哪些呢?有这个滚动窗口的window啊,Ting window,还有这个滑动窗口的,呃,这个sliding window对吧,另外还有绘画窗口session window的,那这三个都有,另外还有一个,还有一个什么呢。全局窗口global window window对吧?啊,这是干什么玩意儿呢?啊对,这个直接说就是所有的数据全放到一个窗口里边去,那大家就会想到这个窗口那就变成什么了,就变成无限流了,对不对,就变成我们的无限流了,从头到到尾一直没有结束啊,大家就会发现它是这个窗口是没有结束时间的,呃,所以就是所有数据都属于它,所以这个其实是一般是用来做什么呢?是用来去自定义一些东西的时候。
06:24
然后因为它没有结束时间,所以我们就要自定义什么时候去触发这个窗口计算对吧?啊,把这些东西全部自定义啊,这就是更加灵活的一种方式了。好,那我们简单的看看这个不同东西的它的这个代码实现是怎么实现的啊,大家看到滚动时间窗口很简单,Time window里边传一个数对不对?那同样滑动时间窗口怎么传呢?Time window还是time window对吧?里边传俩数对吧?呃,这个传两个数,那那传俩数这个是代表什么含义呢?对,大家就会想到前面这个是window size,后边那个是slide,对,滑动距离这个很很简单啊,一看就知道它是什么意思诶另外大家会看到绘画窗口怎么去创建的。
07:14
诶,这个就比较复杂一点了,大家看里边传的就不是直接传这个time了,对吧?诶大家就会想到前面不是说window里边要传的是一个window a signer吗?为什么你前面这里就直接传了一个时间呢?啊大家会想到是不是这个time window和count,后面我们要说那个count window这两个算子啊,这两个操作方法是不是已经封装了一一层啊给我们对吧?它就相当于已经实现了一个点window里边给一个time的time window的一个sign对吧?相当于已经给我们实现了这个东西了啊所以接下来大家看这个就是就是没有再包一层的这种情形啊,绘画窗口没有没有再包一层,大家看点window里面传了一个什么even time session Windows啊,所以大家会看到这里是一个事件时间啊啊,这涉及到这个时间的概念,呃,那个下节课我们再给大家讲这个事件时间。
08:14
就是什么东西啊,大家直观的就是说基于某个时间的一个session window,对吧,然后后面with GAP with GAP就是什么?对它的那个时间间隔是多少,隔多长时间,就算这个session关闭了,所以是十分钟的一个呃间隔的这样定义了一个session window啊好,接下来我们再看这个count window,那也很简单对不对,呃,这个count window5,那是不是就是五个一个窗口对吧,滚动来计数,那如果是count window12呢?大那就是十个一个窗口对吧,然后隔两个划一下对不对,然后下下面再去统计十个,哎,就是很简单啊,大家大概的看一下应该就知道怎么操作了,好那呃,接下来再给大家讲一下这个窗口函数吧,窗口函数这个东西啊,就是我们所说的前面光是定义了一个aign。
09:10
那是我们已经知道了,这些数据来了之后,应该是属于哪个窗口,对不对啊,窗口都已经划分好,都已经定义好了,那到底这个窗口到它关闭的时候,你要干嘛呢。这个是不是得自己定义啊?呃,大家会想到这个是需要我们再去定义的,所以那后面我们就要再跟上一个操作,这个操作就是所谓的window function,这个window方式里边就定义了,我们要对这个窗口里边已经拿到这些数据啊,你到底要干什么事情呢?就在这里去定义啊,当然window function本身是一个比较大的概念啊,呃,它整体来讲又可以分成两类,哪两类呢?一个叫增量聚合函数。啊,增量聚合函数它的意思是什么呢?那大家会想,首先它是个聚合函数对吧?啊,聚合函数就是比方说像我们前面有reduce对吧?啊,有一个前面的聚合结果来一条数据,再聚合一次来一条,再或者我们想到sum是不是也是聚合啊,对吧?呃,这些简单操作都是聚合啊,那大家会想到,呃,它的这个增量又是什么意思呢?
10:18
哎,增量就是说我这不是一个窗口吗?大家能想到这窗口正常来讲做计算是不是要等到我这个窗口结束的时候,收集到所有数据的时候,哎,才去算一下呀,才去算的这个窗口里面到底有什么东西,对吧?这个增量聚合就是说在这个窗口内部也按照流处理的这种方式。来一条数据就算一下,来一条数据就聚合一下,就算一次,然后这个过程是不是就要保存一个状态啊,大家想对吧,保存一个中间状态,哎,那大家会会想到这个有什么好处啊,它是不是就会实时性比较好啊,对吧,你计算就会比较快,但是大家会想到你既然是window嘛,Window的计算嘛。
11:09
你前面算就是这个算的快没用,最后输出是不是一定得等到window关闭的时候才能输出啊,但是大家就会想到你最后window关闭的时候,我是不是要算的也简单了,对吧?你正常来讲,你那个数据所有都来了之后,那是一堆数据,你要便利,然后一个一个去算,那这个计算肯定有很复杂,我大部分的这个数据计算都在前面就完成了,你等到window关闭的时候,我有可能就不用算什么了,或者说我最多就算最后的一条数据聚合完了就完事,对不对,那这个就简单很多啊,当然了,它一方面是简单高效很多,而且节省空间,中间就保存一个状态,对吧,要不然你是不是得把那个所有之前所有的数据都存下来,诶,这是它的好处,呃,但是也有就是缺点,那缺点就是说这种函数它能做的操作很简单,基本上就是就是这种增量聚合对吧,就都是聚合式的这种操作才能才能这么干,呃,那。
12:10
典型的就是reduce function。前面我们已经看了,对吧,点reduce或者是aggregate方式啊,就是聚合相关的一些,这是一个函数类啊,就是我们可以自定义这样的一个average的方式。除了这个增量聚合函数之外呢,还有另外一类,那就是所谓的全窗口函数full window function,那那顾名思义,大家就会想到它跟那个增量聚合函数不一样的就是什么呢?你那个是来一条数据就处理一个,这个就不是了,全窗口嘛,我一定要等到所有数据都来了之后再去做操作,对吧?啊,所以大家会想到就是他先要把所有的数据先暂存起来,先存下来,然后等到窗口关闭的时候,要计算的时候,再去遍利所有数据算一遍,这就是全窗口函数啊,那大家会想到这个肯定就是要占的空间就大了,对不对,算起来也麻烦了,但是它能做的事情是不是就很多啊,哎,那其实很简单,有一个很很直观的一个一个事情啊,大家想一想,假如说我要做排序。
13:22
所有的这个就是数据窗口内所有数据做排序,那大家可以想到就是说你如果要是说就是来一条数据就排一次序,来一条数据就排一次序,这个有点像是这个就是插入排序对吧?呃呃或或或者说就是说我们可以在这个有有就是已经呃排好序的数据里面去做排序,当然这个相对来讲也还时间复杂度不是太高。但是你想其实这个你来一次其实得便利很多数,对吧,在某种情况下,其实这个并不是特别划算,你还不如等所有的数据都到了之后,一次排是不是直接搞定了,对吧,你写一个快排,或者说直接写一个什么样的规定排序,直接把它搞定就完事了,所以这个过程就是有些可能用全窗口函数更好,甚至有些可能你就是来一个就处理,可能就没办法,对吧,可能就根本没没办法做到,那那这种情况你就只有用这种全窗口函数去做了啊这是。
14:25
这一部分,呃,这里要跟大家说的就是说呃做的这个操作啊,前面我们已经给给大家讲了那个。呃,大家还记得吗?我们说从那个data stream,然后经过K之后,对变成了一个kid stream,我这里面就简写了啊,Kid stream。然后大家会想到k stream是不是可以做那个window操作啊,对吧,做了那个点window之后,就得到了一个window stream,所以大家要注意啊,这里又得到了新的数据结构了,这个数据结构叫window stream。
15:09
呃,这个就是大家知道什么意思就可以了啊,另外我们当时说还可以直接在那个data stream基础上直接去做一个操作,直接开窗,对吧,它是能做什么来着,叫WINDOW2对这个操作。它生成的叫all window。对吧,All window the string啊,所以大家看到这些是这个生成了不同的这个数据结构啊,那现在我们又应用窗口函数了,增量聚合或者全窗口函数,它又会得到什么呢?最后就全返回到data stream去。大家应该能想到对不对,对吧,应用这个window function啊,就直接能够再回到data stream,所以我们最后最核心的还是data STEM和k stream,对不对,那操作都是以他们为主的啊,啊大家知道一下这个这个操作,另外再给大家简单的了解一下其他的一些可选的API,就是在这个window里面还有什么A呢?前面的那两个API就是一个是window,对吧,就是那个窗口的分配器,另外还有一个是后面的那个处理window function,对吧?这两步是必须,你至少得知道窗口怎么开,然后得知道窗口收集起来的数据怎么处理,对吧?这两步是必须的,剩下这些都不必须。
16:37
都是可选的啊,但是大家得了解一下啊,大概了解一下,首先有一个trigger trigger是什么东西呢?哎,顾名思义啊,触发器对吧,它是能够控制什么,能够去定义window到底什么时候关闭,来触发我们的那个计算,然后输出结果。这是trigger啊,那他就会想到那它是可选项,那可以不写吗?如果不写的话,默认的trigger应该是怎么trigger呢?
17:07
那如果我们是time window的话,那其实就是大家会想到啊,它trigger是怎么出发,那就是时间达到了那个当前窗口的结束时间的时候,A的时候,对吧,是不是就trigger啊对,它自然就是这样去做的好,然后还有一个aator editator是什么呢?A editor是移除器,移除器的意思是说它可以在里边去定义哪些特定的元素数据可以把它除去,把它删掉。而这而且这个操作就是说你可以定义,就是在在窗口出发前去移除也可以,窗口出发后那个移除也可以,你可以去定义这些,就有可能我这个窗口统计的时候,这些数我就不要了。我把它删掉,不统计。啊,大家可能会觉得,诶这个好像也挺奇怪,对吧,为什么在这里边再去做一个删除,这就是适应适用一些那个特定的一些这个自定义的场合,对吧?比如说前面我们说过那个不是有那个global window吗?全全部的那个数据嘛,全局窗口嘛,那他肯定要自定义那个触发,对不对啊,有可能大家会想到,那我定义那个触发器的时候,有可能就是前一次触发过的那个数据。
18:24
处理完的数据啊,有可能后面有很多东西就不需要了,对吧,所以我需要用这个涤除器,把它从我这个全窗口里边,因为我那个全窗口的所有数据都有了吧,把它移除掉之前已经算完的东西,那这些东西都不要了,对吧?啊,就保持我的那个状态,不要占太多的那个空间啊,就是这样的一个逻辑。好,另外还有几个,这个其实还挺有意思,需要大家了解一下,比方说点lo的lateness,大家字面去理解,这是什么东西啊,啊,这是允许处理迟到的数据啊,那大家就会想到我们之前不是给大家讲过这个,呃,整个这个数据流里边,我们在分布式的系统里边有可能出现延迟对吧?网络延迟有可能出现乱序数据嘛,哎,我本来要收集的数据,结果该收集的时候还没没来对吧,过了一段时间他才来了啊,那大家就会想到我。
19:26
能不能在过了窗口关闭时间之后,我再去处理一些迟到的数据呢?还是可以的,弗link给我们提供了这样的一个啊,这种方便灵活的方式就是你只要调用了点aloud lateness,你就可以在窗口关闭时间已经到了之后,再去允许一段时间延迟,再去处理这个迟到的数据,也把它添加到窗口计算里面去啊,那大家可能就会想到,那如果这个东西不指定的话,那会怎么样?对,不指定的话,那默认的这个就是窗口关闭时间一到,是不是所有的数据就都清空了,这个窗口就清空了,对吧,窗口就直接关闭了,那迟到的数据是不是就全部就都丢掉了呀?啊对,默认是这样的一个行为啊,你如果还想处理迟到数据,那就加上这个,那大家会想到,那我这个东西就是说呃,不能无限期去等啊,对吧,这个东西肯定也是有一些时间限限制的,那如果超过这个时间限限制的这个延迟时间的这个数据,那是不是就会被丢掉了,但是我还不想让它真就丢了,我只是可能窗口计算这个不再等他了,窗口就可以真的把这个关闭给销毁掉了,但是我还想把它再放到另外的一个流里边去做后续,对吧,我再去统计有哪些这个迟到数据没算上,我是不是可以把它放到另外一个流里边去做处理呢?也是可以的,弗Li还提供了这样的一个方法,就是可以把它输出到一个。
20:59
特殊数流里面去,就是塞output late data迟到的数据塞到特殊枢流里面去,那当然你既然要把它放到特殊数流,最后是不是还应该能够把它从测试流里边拿出来啊,对吧?所以后边data stream就还有一个方法叫get set output获取当当时我们定义好的那个测试处理,呃,这就是呃,Window里边可以调用的很多的这种方法API。
21:27
啊,这个大家就是先有一个大概的了解,后面我们用到的时候再给大家具体做一个具体的讲解啊,然后给大家看一下这个window API的一个总览啊,这就是它可以基于kid,呃,Kid stream去做操作,那么这个可以认为是一个key Windows对吧?啊大家看基于KY之后做的操作啊,就是先KY,然后点window,这里边是AS对不对,这是必须要传的一个东西,然后这里边中括号括起来的就都是可选项。来,大家直接看最下边,这里边有一个不是可选项的必须要的,这是个什么?这就是我们那个window方式对不对啊,大家看啊,可以reduce every,可以fo apply,当然还可以process啊,前面我们没有提的一个就是说process window process function,就是一个all window的function对吧,它不是增量聚合的,这些都是,呃,这个reduce aggregate,呃,这这两个,这是这是那个增量聚合的后边for就属于那个全窗口函数了啊。
22:31
然后大家再看这就有trigger avatar要调用的时候,就就在这个位置,大家看就这样的啊,就是一串这个串下来的所有整个这个合起来就是我们的一个window。任window window算子的一个操作啊,所以大家看就是整个这一串都算window,呃,当然了就还可以,是不是P之后的,那那就是我们就WINDOW2了,对不对啊,大家看啊,直接WINDOW2给一个a signer后面是不是一样啊,完全一样对不对,所以这个就不讲了啊,大家就大概知道他是怎么样做就可以了。
我来说两句