1.Flink中的時(shí)間語(yǔ)義
1)在Flink的流式處理中,會(huì)涉及到時(shí)間的不同概念,如下圖所示:

Event Time:是事件創(chuàng)建的時(shí)間。它通常由事件中的時(shí)間戳描述,例如采集的日志數(shù)據(jù)中,每一條日志都會(huì)記錄自己的生成時(shí)間,F(xiàn)link通過(guò)時(shí)間戳分配器訪問(wèn)事件時(shí)間戳。
Ingestion Time:是數(shù)據(jù)進(jìn)入Flink的時(shí)間。
Processing Time:是每一個(gè)執(zhí)行基于時(shí)間操作的算子的本地系統(tǒng)時(shí)間,與機(jī)器相關(guān),默認(rèn)的時(shí)間屬性就是Processing Time。
2)EventTime的引入
在Flink的流式處理中,絕大部分的業(yè)務(wù)都會(huì)使用EventTime,一般只在EventTime無(wú)法使用時(shí),才會(huì)被迫使用ProcessingTime或者IngestionTime。
默認(rèn)情況下,F(xiàn)link框架中處理的時(shí)間語(yǔ)義為ProcessingTime,如果要使用EventTime,那么需要引入EventTime的時(shí)間屬性,引入方式如下所示:
importorg.apache.flink.streaming.api.TimeCharacteristic
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
2.WaterMark
1)基本概念
我們知道,流處理從事件產(chǎn)生,到流經(jīng)source,再到operator,中間是有一個(gè)過(guò)程和時(shí)間的,雖然大部分情況下,流到operator的數(shù)據(jù)都是按照事件產(chǎn)生的時(shí)間順序來(lái)的,但是也不排除由于網(wǎng)絡(luò)、分布式等原因,導(dǎo)致亂序的產(chǎn)生,所謂亂序,就是指Flink接收到的事件的先后順序不是嚴(yán)格按照事件的Event Time順序排列的。

那么此時(shí)出現(xiàn)一個(gè)問(wèn)題,一旦出現(xiàn)亂序,如果只根據(jù)eventTime決定window的運(yùn)行,我們不能明確數(shù)據(jù)是否全部到位,但又不能無(wú)限期的等下去,此時(shí)必須要有個(gè)機(jī)制來(lái)保證一個(gè)特定的時(shí)間后,必須觸發(fā)window去進(jìn)行計(jì)算了,這個(gè)特別的機(jī)制,就是Watermark。
Watermark是一種衡量Event Time進(jìn)展的機(jī)制。
Watermark是用于處理亂序事件的,而正確的處理亂序事件,通常用Watermark機(jī)制結(jié)合window來(lái)實(shí)現(xiàn)。
有序流的Watermarker如下圖所示:(Watermark不設(shè)置延遲)

亂序流的Watermarker如下圖所示:(Watermark延遲時(shí)間設(shè)置為2s)

Watermark是由數(shù)據(jù)攜帶的,一旦數(shù)據(jù)攜帶的Watermark比當(dāng)前未觸發(fā)的窗口的結(jié)束時(shí)間要晚,那么就會(huì)觸發(fā)相應(yīng)窗口的執(zhí)行。由于Watermark是由數(shù)據(jù)攜帶的,因此,如果運(yùn)行過(guò)程中無(wú)法獲取新的數(shù)據(jù),那么沒(méi)有被觸發(fā)的窗口將永遠(yuǎn)都不被觸發(fā)。
Watermark 就是觸發(fā)前一窗口的“關(guān)窗時(shí)間”,一旦觸發(fā)關(guān)門那么以當(dāng)前時(shí)刻為準(zhǔn)在窗口范圍內(nèi)的所有所有數(shù)據(jù)都會(huì)收入窗中。
只要沒(méi)有達(dá)到水位那么不管現(xiàn)實(shí)中的時(shí)間推進(jìn)了多久都不會(huì)觸發(fā)關(guān)窗。
自己理解:對(duì)窗口設(shè)置一個(gè)延遲時(shí)間,用來(lái)處理亂序延時(shí)數(shù)據(jù)。如上圖所示,未設(shè)置延遲時(shí),第一個(gè)窗口的觸發(fā)Watermark為5s;設(shè)置了2s延遲之后,第一個(gè)窗口的觸發(fā)Watermark為>=7s。