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