窗口
窗口的概念
Flink是一种流式计算引擎,主要是来处理无界数据流的,数据源源不断、无穷无尽。想要更加方便高效地处理无界流,一种方式就是将无限数据切割成有限的“数据块”进行处理,这就是所谓的“窗口”。在Flink中,窗口就是用来处理无界流的核心。我们很容易把窗口想象成一个固定位置的“框”,数据源源不断地流过来,到某个时间点窗口该关闭了,就停止收集数据、触发计算并输出结果。例如,我们定义一个时间窗口,每10秒统计一次数据,那么就相当于把窗口放在那里,从0秒开始收集数据;到10秒时,处理当前窗口内所有数据,输出一个结果,然后清空窗口继续收集数据;到20秒时,再对窗口内所有数据进行计算处理,输出结果;依次类推,如6-13所示。这里注意为了明确数据划分到哪一个窗口,定义窗口都是包含起始时间、不包含结束时间的,用数学符号表示就是一个左闭右开的区间,例如0~10秒的窗口可以表示为[0,,这里单位为秒。对于处理时间下的窗口而言,这样理解似乎没什么问题。因为窗口的关闭是基于系统时间的,赶不上这班车的数据,就只能坐下一班车了——正如上中,0~10秒的窗口关闭后,可能还有时间戳为9的数据会来,它就只能进入10~20秒的窗口了。这样会造成窗口处理结果的不准确。然而如果我们采用事件时间语义,就会有些费解了。由于有乱序数据,我们需要设置一个延迟时间来等所有数据到齐。比如上面的例子中,我们可以设置延迟时间为2秒,如6-14所示,这样0~10秒的窗口会在时间戳为12的数据到来之后,才真正关闭计算输出结果,这样就可以正常包含迟到的9秒数据了。但是这样一来,0~10秒的窗口不光包含了迟到的9秒数据,连11秒和12秒的数据也包含进去了。我们为了正确处理迟到数据,结果把早到的数据划分到了错误的窗口——最终结果都是错误的。所以在Flink中,窗口其实并不是一个“框”,流进来的数据被框住了就只能进这一个窗口。相比之下,我们应该把窗口理解成一个“桶”,如6-15所示。在Flink中,窗口可以把流切割成有限大小的多个“存储桶”第一个数据时间戳为判断之后创建第一个窗口[0,,并将2秒数据保存进去;后续数据依次到来,时间戳均在[0,范围内,所以全部保存进第一个窗口;11秒数据到来,判断它不属于[0,窗口,所以创建第二个窗口[10,20),并将11秒的数据保存进去。由于水位线设置延迟时间为2秒,所以现在的时钟是9秒,第一个窗口也没有到关闭时间;之后又有9秒数据到来,同样进入[0,窗口中;12秒数据到来,判断属于[10,20)窗口,保存进去。这时产生的水位线推进到了10秒,所以[0,窗口应该关闭了。第一个窗口收集到了所有的7个数据,进行处理计算后输出结果,并将窗口关闭销毁;同样的,之后的数据依次进入第二个窗口,遇到20秒的数据时会创建第三个窗口[20,30)并将数据保存进去;遇到22秒数据时,水位线达到了20秒,第二个窗口触发计算,输出结果并关闭。这里需要注意的是,Flink中窗口并不是静态准备好的,而是动态创建——当有落在这个窗口区间范围的数据达到时,才创建对应的窗口。这里我们认为到达窗口结束时间时,窗口就触发计算并关闭,事实上“触发计算”和“窗口关闭”两个行为也可以分开,这部分内容我们会在后面详述。
窗口的分类
文章为作者独立观点,不代表 股票程序化软件自动交易接口观点