4個角度輕鬆理解 Flink中的Watermark

yscoder發表於2020-11-14

目錄

有快取就必然有延遲

必須勇敢地輸出排序流的第一個結果

watermark 定義了何時不再等待更早的資料

設想不同的策略來生成 watermark


當我們第一次接觸 Flink 時往往會對其中的 watermark 感到困惑。但實際上 watermark 並不複雜。在本文中我們將通過一個簡單的例子來說明為什麼需要水印以及它們如何工作。

在下文中的例子中,我們有一個帶有時間戳的事件流,但是由於某種原因流中的事件並不是按順序到達的。圖中的數字代表事件發生的時間戳(Event-time)。第一個事件在時間4達到,它後面跟著的是發生在更早時間(時間 2)的事件,以此類推:

注意這是一個按照事件時間(Event-time)處理的例子,上面所述的時間戳所表示的是事件真實發生時間,而非事件處理的時間(Processing-Time) 。事件時間(Event-Time)處理的強大之處在於,無論是在處理當前的資料還是重新處理歷史(資料重放)的資料,基於事件時間建立的流計算應用都可以保證最終執行結果是一致的。

假設我們現在正在嘗試建立一個流計算排序運算元。即將一個亂序到達的事件流按照事件時間進行順序輸出。資料流中的第一個元素的事件時間是 4,但是我們不能直接將它作為排序後資料流的第一個元素進行輸出。因為資料是亂序到達的,也許有一個更早發生的資料還沒有到達。實際上,我們在上面的例子中可以提前預知到這個流中元素2 的事件事件比4更早,我們的排序運算元至少要等到 2 這條資料的到達後再做輸出。

有快取就必然有延遲

資料流中的第一個元素的事件時間是 4,但是我們不能直接將它作為排序後資料流的第一個元素進行輸出。因為資料是亂序到達的,也許有一個更早發生的資料還沒有到達。實際上,我們在上面的例子中可以提前預知到這個流中元素2 的事件事件比4更早,我們的排序運算元至少要等到 2 這條資料的到達後再做輸出。

必須勇敢地輸出排序流的第一個結果

如果我們假設事件2已經達到,而且我們相信2之前還有更早的事件需要等待,在上面例子中的資料流中, 實際上已經沒有比2更早的事件了,我們可能會永遠等待下去。總之,我們的應用程式不能保證一定有更早的資料還未到達,所以不能無條件的等下去。

watermark 定義了何時不再等待更早的資料

我們需要某種策略用於定義了對於任何帶事件事件的資料流,何時停止等待更早資料的到來。

Flink 中的事件時間處理依賴於一種特殊的帶時間戳的元素,稱為 watermark,它們會由資料來源或是 watermark 生成器插入資料流中。具有時間戳 t 的 watermark 可以被理解為斷言了所有時間戳小於或等於 t 的事件都(在某種合理的概率上)已經到達了。

何時我們的排序運算元應該停止等待,然後將事件 2 作為首個元素輸出?答案是當收到時間戳為 2(或更大)的 watermark 時。

設想不同的策略來生成 watermark

我們知道每個事件都可能會延遲一段時間才到達且這些延遲差異會比較大,有些事件會比其他事件延遲更多。一種簡單的方法是假設這些延遲不會超過某個最大值。Flink 把這種策略稱作 "有界無序生成策略"(bounded-out-of-orderness)。當然也有很多更復雜的方式去生成 watermark,但是對於大多數常規應用來說,固定延遲方式已經足夠了。

往期精選▼

Flink中Checkpoint和Savepoint 的 3 個不同點

Flink實現固定時長或訊息條數的觸發器 

使用 Broadcast State 的 4 個注意事項

3種Flink State Backend | 你該用哪個?

100%會被問到的兩道Flink面試題,你會了麼?

識別二維碼, 關注我們

相關文章