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

2022-07-10 14:51:16 字數 1800 閱讀 4206

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,但是對於大多數常規應用來說,固定延遲方式已經足夠了。

原文:

watermark定義了什麼時候不用等待更早的資料.

假設現在時間戳是100秒的資料到了, 我們還等待到什麼時候才開始計算呢?

要等到97秒的資料, 90秒的資料,還是50秒的資料呢?

這時候就要設定規則了.

我規定, 100秒的資料到了後,我再等待3秒鐘, 97秒的資料到了,我就開始計算.

Flink原理與實現 理解Flink中的計算資源

本文所討論的計算資源是指用來執行 task 的資源,是乙個邏輯概念。本文會介紹 flink 計算資源相關的一些核心概念,如 slot slotsharinggroup colocationgroup chain等。並會著重討論 flink 如何對計算資源進行管理和隔離,如何將計算資源利用率最大化等等...

輕鬆理解Shell指令碼中的變數(二)

環境變數 使用者在作業系統時使用到的命令搜尋路徑 發現其不用絕對路徑就可以執行指令碼,因為他寫在 path中。我們將它移到 mnt 中,發現只有執行絕對路徑可以執行指令碼。那麼我們如果想讓 mnt 下的指令碼也不用絕對路徑就能執行,我們可以 設定方式 使用者變數設定 thermal使用者就可以直接用...

從兩個角度理解為什麼 JS 中沒有函式過載

函式過載是指在同一作用域內,可以有一組具有相同函式名,不同引數列表 引數個數 型別 順序 的函式,這組函式被稱為過載函式。過載函式通常用來宣告一組功能相似的函式,這樣做減少了函式名的數量,避免了名字空間的汙染,對於程式的可讀性有很大的好處。但是在 js 如果不通過一些方法是無法實現過載的,可以從以下...