雖說(shuo)水(shui)位線(xian)(Watermark)表明早于它(ta)的(de)事件(jian)(jian)(jian)不(bu)應該再出現,但是接(jie)收到水(shui)位線(xian)以前的(de)的(de)消息(xi)是不(bu)可避免(mian)的(de),這就是所(suo)謂(wei)的(de)遲到事件(jian)(jian)(jian)。實際上遲到事件(jian)(jian)(jian)是亂序(xu)(xu)事件(jian)(jian)(jian)的(de)特例,和(he)一般亂序(xu)(xu)事件(jian)(jian)(jian)不(bu)同的(de)是它(ta)們(men)的(de)亂序(xu)(xu)程度(du)超出了水(shui)位線(xian)的(de)預計,導(dao)致窗口在它(ta)們(men)到達之(zhi)前已(yi)經關閉(bi)。
遲到事件(jian)出現時窗口已經關閉(bi)并產出了計算結果,因(yin)此處(chu)理的方法(fa)有3種:
- 重新激活已(yi)經關閉(bi)的窗(chuang)口并重新計算以(yi)修(xiu)正(zheng)結果。
- 將遲到事(shi)件收集(ji)起來(lai)另外處理。
- 將遲(chi)到事(shi)件視為(wei)錯誤消息(xi)并丟棄。
Flink 默(mo)認的(de)處(chu)理方式(shi)是第3種直接丟棄,其他兩種方式(shi)分(fen)別使用Allowed Lateness和 Side Output。
Side Output機制可以將遲(chi)到事件單(dan)獨放入(ru)一(yi)個數據(ju)流分支,這(zhe)會作為 window計算結果(guo)的副產品,以便用戶獲取并對其進行特(te)殊處(chu)理。Allowed Lateness機制允許用戶設(she)置一(yi)個允許的最大遲(chi)到時長(chang)。
Flink 會在窗(chuang)口關閉后一直(zhi)保存窗(chuang)口的(de)狀態直(zhi)至超過允許遲(chi)到(dao)時長(chang),這期(qi)間的(de)遲(chi)到(dao)事件不(bu)會被丟(diu)棄,而是默(mo)認會觸(chu)發窗(chuang)口重新計算。
因為保存窗口狀態需要額外內存,并且如果窗口計算(suan)(suan)使(shi)用了 ProcessWindowFunction API 還(huan)可能(neng)使(shi)得每個遲到(dao)事件(jian)觸發一次窗口的(de)全(quan)量計算(suan)(suan),代價比較大(da),所以(yi)允許遲到(dao)時(shi)長不宜設(she)得太(tai)長,遲到(dao)事件(jian)也不宜過(guo)多,否則應(ying)該考慮降低水位線提高的(de)速度或者調(diao)整算(suan)(suan)法。
這里總結機制(zhi)為:
- 窗(chuang)口window 的作用(yong)是為了周期性(xing)的獲取數據。
- watermark的(de)作用是防止(zhi)數據出現亂序(xu)(經常),事件時間內(nei)獲取不到(dao)指(zhi)定的(de)全部數據,而做(zuo)的(de)一種保險方法。
- allowLateNess是將窗(chuang)口關閉時間再延(yan)遲一段時間。
- sideOutPut是最后兜(dou)底(di)操(cao)作(zuo),所有過期延遲數據(ju),指(zhi)定窗口(kou)已經(jing)徹底(di)關(guan)閉了,就(jiu)會把數據(ju)放到側輸出流(liu)。