Flink有關於水位線(WaterMark)相關問題


要想說清楚Flink水位線(WaterMark),前提需要弄清楚幾個概念。

第一個是時間概念:

在Flink中有三個時間概念,分別是事件時間,采集時間,和系統時間。

事件時間:在客觀世界中產生的時間,比如用戶點擊網頁產生了一條時間日志,這個時間就是事件時間。

采集時間:我們用Flink采集日志到達Flink的時間為采集時間。

系統時間:這個時間使我們在寫邏輯代碼時會調用的時間,比如在程序里面寫 System.currentTimeMillis() 命令

當有了時間概念,那我們真正關心的業務時間是哪個呢? 老板不會關心Flink什么時候采集的,更不會關心你什么時候在當前系統調用的時間,所以答案肯定是日志發生的時間,也就是用戶什么時候點擊的。

那我們怎么通過日志的事件時間對事件進行處理呢?

如下圖所示:

當存在網絡延時的情況下,本來進入窗口 A 的 2號數據在0-5秒內沒有進入窗口A,但是它仍然在采集后出現在A窗口里面,這是為什么?

因為Flink將每條日志的客觀產生的時間紀錄下來,2號數據就是0-5秒產生的,Flink就會把它放在A窗口。只不過它是在5-10秒的時候被放進去的。那這樣的話,我們應該什么時候去關閉窗口呢。

因為有種假設,如果有一個屬於這個窗口的數據一年后才過來。那我豈不是要一年才能關窗。所以Flink為了解決這個問題設置了一個過期時間。設置方式如下:

其中10秒為過期時間,element._2為我們從日志中讀取中的客觀產生的時間戳。

雖然有了過期時間,但是Flink並不會只在過期時間之后閉窗。

實際上,Flink閉窗取決於水位線和過期時間的共同作用,那什么是水位線呢?

水位線指的是Flink內部會在每200ms(默認值,可以設置)生成一個時間戳,它的大小等於當前數據集合里面最大的客觀時間減去延時時間。

Flink為什么這么設置呢,我們直接把0-5窗口的數據在延時10秒后關閉不就可以了么。答案是不可以

因為我們這個15秒是系統時間延時的10秒,但是我們要的是真正的客觀的時間延時10秒。

這么說可能不太好理解,舉個誇張的例子,客觀世界中在0-15內(其中5秒的窗口,加上10秒的延時)內產生了十條數據,之后十年就不會再產生數據了,那Flink應不應該關窗?

實際上不應該關窗,因為計算機在不知道下一條日志客觀時間的時候,他是不知道此時窗口進行到哪里了。只有在出現客觀時間大於十五秒的時候,之前0-5秒的窗口才會關閉。

因此我們為了記錄客觀時間引入了水位線的概念。用這個數字來記錄客觀世界的最大時間。

我們只需要比較:水位線是否大於窗口+延時時間,來判斷是否該關窗。

當水位線  > 窗口    ------>關窗

當水位線  < 窗口    ------>不關窗

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM