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