Flink對(duì)于延遲數(shù)據(jù)的解決方法:allowedLateness
當(dāng)我們對(duì)流設(shè)置窗口后得到的WindowedStream對(duì)象就可以使用allowedLateness方法

該方法傳入一個(gè)Time值,設(shè)置允許的長(zhǎng)期延遲(遲到)的時(shí)間。
和watermark不同。
未設(shè)置allowedLateness(為0),當(dāng)watermark滿足條件,會(huì)觸發(fā)窗口的 執(zhí)行 + 關(guān)閉
當(dāng)設(shè)置了allowedLateness,當(dāng)watermark滿足條件后,只會(huì)觸發(fā)窗口的執(zhí)行,不會(huì)觸發(fā)窗口關(guān)閉。
也就是,watermark滿足條件后會(huì)正常觸發(fā)窗口計(jì)算,將已有的數(shù)據(jù)完成計(jì)算。?
但是,不會(huì)關(guān)閉窗口。如果在allowedLateness允許的時(shí)間內(nèi)仍有這個(gè)窗口的數(shù)據(jù)進(jìn)來,那么每進(jìn)來一條,會(huì)和已經(jīng)計(jì)算過的(被watermark觸發(fā)的)數(shù)據(jù)一起在計(jì)算一次。
示例代碼
執(zhí)行結(jié)果

如圖,1000 4999 屬于窗口 0 ~ 5000的數(shù)據(jù)
當(dāng)7999提交的時(shí)候,滿足了watermark的觸發(fā),將0 – 5000這個(gè)窗口的數(shù)據(jù)計(jì)算了(未關(guān)閉)
輸出結(jié)果(a, 2)
當(dāng)輸入8999的時(shí)候,watermark已經(jīng)被推到了 5999了,已經(jīng)超出了0-5000窗口的結(jié)束時(shí)間
但是當(dāng)我們提交了a 3000 發(fā)現(xiàn),0-5000這個(gè)窗口還在,并且3000和原本的1000 4999聯(lián)合一起計(jì)算了一次
得到(a, 3)的結(jié)果
這樣證明:
長(zhǎng)期延遲數(shù)據(jù)處理機(jī)制,如果設(shè)置了時(shí)間,watermark只會(huì)完成觸發(fā)窗口計(jì)算,而不會(huì)關(guān)閉窗口
同時(shí),當(dāng)有新數(shù)據(jù)進(jìn)入這個(gè)窗口還會(huì)和已經(jīng)計(jì)算過的數(shù)據(jù)放在一起再次計(jì)算
當(dāng),當(dāng)前事件時(shí)間 – 水印長(zhǎng)度 – 允許的長(zhǎng)期延遲數(shù)據(jù)時(shí)間 >= 窗口的結(jié)束時(shí)間的時(shí)候, 這個(gè)窗口才會(huì)關(guān)閉

如圖,可見,后續(xù)又輸入了9999, 這個(gè)9999導(dǎo)致了0-5000窗口的關(guān)閉
所以再次輸入a 3500 發(fā)現(xiàn)就沒有反應(yīng)了。因?yàn)閷儆谒拇翱谝呀?jīng)關(guān)閉了。
9999 – 3000 – 2000 = 4999? ?3000是水印長(zhǎng)度? 2000是允許的長(zhǎng)期延遲數(shù)據(jù)時(shí)間
4999 就是0-5000這個(gè)窗口的觸發(fā)點(diǎn),
總結(jié)
水?。憾唐谘舆t,達(dá)到條件后觸發(fā)計(jì)算并且關(guān)閉窗口(觸發(fā)+關(guān)閉同時(shí)進(jìn)行)
水印+allowedLateness :短期延遲+ 等待長(zhǎng)期延遲效果,達(dá)到水印條件后,會(huì)觸發(fā)窗口計(jì)算,但是不關(guān)閉窗口。事件時(shí)間延遲達(dá)到水印+allowedLateness之和后會(huì)關(guān)閉窗口
