1.時(shí)間類(lèi)型
Flink實(shí)時(shí)計(jì)算劃分窗口時(shí),如果使用時(shí)間作為劃分窗口的依據(jù),時(shí)間有不同的類(lèi)型,分為Event Time、Ingestion Time、Processing Time。Flink默認(rèn)使用的是Processing Time,程序運(yùn)行如果使用不同的時(shí)間類(lèi)型,計(jì)算的結(jié)果完全不同,可以根據(jù)實(shí)際需求選擇使用具體哪一種時(shí)間類(lèi)型

Event Time 事件時(shí)間
在大數(shù)據(jù)領(lǐng)域,日志服務(wù)器生成的一條數(shù)據(jù)也可以稱(chēng)為一個(gè)事件。Event Time是指在數(shù)據(jù)產(chǎn)生時(shí)該設(shè)備上對(duì)應(yīng)的時(shí)間,這個(gè)時(shí)間在進(jìn)入Flink之前已經(jīng)存在于數(shù)據(jù)記錄中了。以后數(shù)據(jù)被Flink處理數(shù)據(jù),如果使用Event Time作為時(shí)間標(biāo)準(zhǔn),那么數(shù)據(jù)并不是按照Event Time的先后順序被處理的,由于數(shù)據(jù)可能產(chǎn)生在多個(gè)不同的日志服務(wù)器,然后通常是再將數(shù)據(jù)寫(xiě)入到分布性消息中間件,然后被被Flink拉取進(jìn)行處理時(shí),處理的實(shí)際時(shí)間相對(duì)于數(shù)據(jù)產(chǎn)生的實(shí)際肯定有一定的延遲,并且Event Time可能也是亂序的。那么為什么還要使用Event Time呢?是因?yàn)槭褂肊vent Time時(shí),F(xiàn)link程序可以處理亂序事件和延遲數(shù)據(jù)。并且最重要的功能就是可以統(tǒng)計(jì)在數(shù)據(jù)產(chǎn)生時(shí),對(duì)應(yīng)時(shí)間的數(shù)據(jù)指標(biāo)。
Ingestion Time 進(jìn)入時(shí)間
Ingestion Time指的是事件數(shù)據(jù)進(jìn)入到Flink的時(shí)間。每條數(shù)據(jù)的Ingestion Time就是進(jìn)入到Source Operator時(shí)所在機(jī)器的系統(tǒng)時(shí)間。比如Flink從Kafka消息中間件消費(fèi)數(shù)據(jù),每一條數(shù)據(jù)的Ingestion Time就是FlinkKafkaConsumer拉取數(shù)據(jù)進(jìn)入到TaskManager對(duì)應(yīng)的時(shí)間。Ingestion Time介于Event Time和Processing Time之間,與 Event Time 相比,Ingestion Time程序無(wú)法處理任何無(wú)序事件或延遲數(shù)據(jù),并且程序不必指定如何生成水,F(xiàn)link會(huì)自動(dòng)分配時(shí)間戳和自動(dòng)生成水位線(xiàn)。
Processing Time 處理時(shí)間
Processing Time是指事件數(shù)據(jù)被Operator處理時(shí)所在機(jī)器的系統(tǒng)時(shí)間,是Flink默認(rèn)使用的時(shí)間標(biāo)準(zhǔn),它提供了最好的性能和最低的延遲。但是,F(xiàn)link是一個(gè)在分布式的計(jì)算框架,數(shù)據(jù)從產(chǎn)生到被處理會(huì)有一定的延遲(例如從消息隊(duì)列拉取數(shù)據(jù)到Source,Source再到處理的Operator會(huì)有一定的延遲),所以Processing Time無(wú)法精準(zhǔn)的體現(xiàn)出數(shù)據(jù)在產(chǎn)生的那個(gè)時(shí)刻的變化情況。
設(shè)置時(shí)間類(lèi)型
在不設(shè)置任何的時(shí)間標(biāo)準(zhǔn)的情況下,默認(rèn)使用的是ProcessingTime,如果要使用某一種時(shí)間類(lèi)型作為作為時(shí)間標(biāo)準(zhǔn),那么就要使用StreamExecutionEnvironment的setStreamTimeCharacteristic,傳入TimeCharacteristic其中的一個(gè)的枚舉類(lèi)型參數(shù)
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();//設(shè)置EventTime作為時(shí)間標(biāo)準(zhǔn)
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
//設(shè)置IngestionTime作為時(shí)間標(biāo)準(zhǔn)
//env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);
//設(shè)置ProcessingTime作為時(shí)間標(biāo)準(zhǔn)
//env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);
2.窗口的類(lèi)型
1.滑動(dòng)窗口

將數(shù)據(jù)依據(jù)固定的窗口?度對(duì)數(shù)據(jù)進(jìn)行切片。特點(diǎn):時(shí)間對(duì)?,窗口?度固定,沒(méi)有重疊。滾動(dòng)窗口分配器將每個(gè)元素分配到一個(gè)指定窗口大小的窗口中,滾動(dòng)窗口有一個(gè)固定的大小,并且不會(huì) 出現(xiàn)重疊。例如:如果你指定了一個(gè)5分鐘大小的滾動(dòng)窗口,窗口的創(chuàng)建如下圖所示:
2.滑動(dòng)窗口
滑動(dòng)窗口是固定窗口的更廣義的一種形式,滑動(dòng)窗口由固定的窗口?度和滑動(dòng)間隔組成
特點(diǎn):時(shí)間對(duì)?,窗口?度固定,有重疊

滑動(dòng)窗口分配器將元素分配到固定?度的窗口中,與滾動(dòng)窗口類(lèi)似,窗口的大小由窗口大小參數(shù)來(lái)配置,另一個(gè)窗口滑動(dòng)參數(shù)控制滑動(dòng)窗口開(kāi)始的頻率。因此,滑動(dòng)窗口如果滑動(dòng)參數(shù)小于窗口大小的話(huà),窗口是可以重疊的,在這種情況下元素會(huì)被分配到多個(gè)窗口中
3.會(huì)話(huà)窗口
由一系列事件組合一個(gè)指定時(shí)間?度的timeout間隙組成,類(lèi)似于web應(yīng)用的session,也就是一段時(shí)間沒(méi)有接收到新數(shù)據(jù)就會(huì)生成新的窗口

session窗口分配器通過(guò)session活動(dòng)來(lái)對(duì)元素進(jìn)行分組,session窗口跟滾動(dòng)窗口和滑動(dòng)窗口相比,不會(huì)有重疊和固定的開(kāi)始時(shí)間和結(jié)束時(shí)間的情況,相反,當(dāng)它在一個(gè)固定的時(shí)間周期內(nèi)不再收到元素,即 非活動(dòng)間隔產(chǎn)生,那個(gè)這個(gè)窗口就會(huì)關(guān)閉。一個(gè)session窗口通過(guò)一個(gè)session間隔來(lái)配置,這個(gè)session間隔定義了非活躍周期的?度,當(dāng)這個(gè)非活躍周期產(chǎn)生,那么當(dāng)前的session將關(guān)閉并且后續(xù)的元素將被分配到新的session窗口中去
3.Non-Keyed和Keyed Windows
在劃分Window之前,首先要確定該DataStream是否調(diào)用了key算子將數(shù)據(jù)按照key進(jìn)行分組了。如果沒(méi)有調(diào)用keyBy算子,可以調(diào)用windowAll方法的返回一個(gè)AllWindowedStream,這種window叫做Non-Keyed Windows(未分組的Widnows);如果事先已經(jīng)調(diào)用了keyBy算子,即對(duì)KeyedStream可以調(diào)用window方法返回一個(gè)WindowedStream,這種window叫做Keyed Windows(分組的Widnows)。由于調(diào)用windowAll/window算子后會(huì)生成會(huì)生成新WindowedStream/WindowedStream,所以窗口算也是屬于Transformation
Non-Keyed Windows
未分組的Widonws,即DataSteam直接調(diào)用windowAll算子得到的Windows,Non-Keyed Windows的特點(diǎn)是,在某一個(gè)具體的窗口,所有的數(shù)據(jù)都會(huì)被窗口算子路由到一個(gè)subtask中進(jìn)行運(yùn)算,如果并行度大于1,下一次生成的window的數(shù)據(jù)會(huì)被路由到其他的subtask中進(jìn)行運(yùn)算
Keyed Windows
分組的Widonws,即KeyedStream直接調(diào)用window算子得到的Windows。Keyed Windows的特點(diǎn)是:窗口中的數(shù)據(jù)會(huì)根據(jù)key進(jìn)行分組,key相同的數(shù)據(jù)一定會(huì)被分到同一個(gè)組內(nèi),并被路由到同一個(gè)subtask中,一個(gè)key對(duì)應(yīng)一個(gè)組,一個(gè)subtask中可以有零到多個(gè)組。窗口觸發(fā)會(huì)對(duì)每個(gè)組進(jìn)行計(jì)算,每個(gè)組都會(huì)得到一個(gè)結(jié)果。