雖說水位線(Watermark)表明早于它的事件不應(yīng)該再出現(xiàn),但是接收到水位線以前的的消息是不可避免的,這就是所謂的遲到事件。實際上遲到事件是亂序事件的特例,和一般亂序事件不同的是它們的亂序程度超出了水位線的預(yù)計,導(dǎo)致窗口在它們到達之前已經(jīng)關(guān)閉。
遲到事件出現(xiàn)時窗口已經(jīng)關(guān)閉并產(chǎn)出了計算結(jié)果,因此處理的方法有3種:
- 重新激活已經(jīng)關(guān)閉的窗口并重新計算以修正結(jié)果。
- 將遲到事件收集起來另外處理。
- 將遲到事件視為錯誤消息并丟棄。
Flink 默認的處理方式是第3種直接丟棄,其他兩種方式分別使用Allowed Lateness和 Side Output。
Side Output機制可以將遲到事件單獨放入一個數(shù)據(jù)流分支,這會作為 window計算結(jié)果的副產(chǎn)品,以便用戶獲取并對其進行特殊處理。Allowed Lateness機制允許用戶設(shè)置一個允許的最大遲到時長。
Flink 會在窗口關(guān)閉后一直保存窗口的狀態(tài)直至超過允許遲到時長,這期間的遲到事件不會被丟棄,而是默認會觸發(fā)窗口重新計算。
因為保存窗口狀態(tài)需要額外內(nèi)存,并且如果窗口計算使用了 ProcessWindowFunction API 還可能使得每個遲到事件觸發(fā)一次窗口的全量計算,代價比較大,所以允許遲到時長不宜設(shè)得太長,遲到事件也不宜過多,否則應(yīng)該考慮降低水位線提高的速度或者調(diào)整算法。
這里總結(jié)機制為:
- 窗口window 的作用是為了周期性的獲取數(shù)據(jù)。
- watermark的作用是防止數(shù)據(jù)出現(xiàn)亂序(經(jīng)常),事件時間內(nèi)獲取不到指定的全部數(shù)據(jù),而做的一種保險方法。
- allowLateNess是將窗口關(guān)閉時間再延遲一段時間。
- sideOutPut是最后兜底操作,所有過期延遲數(shù)據(jù),指定窗口已經(jīng)徹底關(guān)閉了,就會把數(shù)據(jù)放到側(cè)輸出流。