1. 程式人生 > >Apache Flink 零基礎入門(十八)Flink windows和Time操作

Apache Flink 零基礎入門(十八)Flink windows和Time操作

Time型別

在Flink中常用的Time型別:

  • 處理時間
  • 攝取時間
  • 事件時間

處理時間

是上圖中,最後一步的處理時間,表示伺服器中執行相關操作的處理時間。例如一些運算元操作時間,在伺服器上面的時間。

如果你以處理時間作為流處理的時間處理方式,那麼所有的基於時間的操作都會使用伺服器的時間,來執行相關的操作。例如:一個小時的處理時間視窗,將會包含一個小時內的到達伺服器內的所有資料。例如應用程式9:15am開始執行,第一個小時的時間處理視窗會包含所有的9:15到10:15內的事件資料,下一個時間視窗是10:15到11:15內的所有資料。

處理時間是最簡單的事件處理方式,並不需要流和機器的時間協調。因此提供了高效能和低延遲。然而在分散式環境中或者非同步環境中處理時間並不能夠提供準確性(也就是說在處理資料時,由於網路的抖動在一個處理時間視窗中例如9:15到10:15,很大可能包括9:00的事件資料)。

事件時間

事件時間是每一個裝置上每一個單獨事件發生的時間例如手機登入APP的日誌時間。這個時間就是這條資料記錄的時間。每一條資料都有一個時間戳表示這條資料的事件發生時間。這個時間取決於每條資料,而並不會依賴於機器的時間。事件時間處理時必須指定如何獲得Event Time watermarks(用來描述Event Time如何處理)。

按照事件時間處理資料,處理結果應該是完全一致,也就是說無論處理多少次結果都是一樣的,這就是所謂的大資料處理的冪等性。 不管事件到達時間和事件是不是有序到達(在生產環境中,資料往往進入到伺服器中的時間和順序是不一定的,有可能先產生的資料後到達伺服器,這取決於很多網路因素)

攝取時間

攝取時間表示某個事件資料進入到Flink的時間。在source操作中,每條記錄都會得到source的當前時間戳,也就是接收到的資料自動會有一個攝取時間,也就是例如時間窗都是基於這個時間來處理的。

攝取時間是處於事件時間和處理時間之間。如上圖所示。攝取時間是有成本的,但是卻是結果可預測的。因為攝取時間使用了穩定的時間戳(在source端只會分配一次),每一條資料的時間戳都是固定的。並且同一攝取時間的資料有可能被分配到不同的處理時間視窗中。

Windows

Windows使我們處理無限資料流(源源不斷的進來)的核心部件。Windows把我們的資料流拆成一個個的buckets。我們需要把運算元作用到buckets上面去。

第一件事情就是需要指定我們的流資料是不是有key,有key和沒有key對應的運算元是完全不一樣的。

Keyed windows

帶keyby,會結合windows一起使用。輸入的資料內容中的任意屬性都可以作為一個key。在這個流上可以允許視窗多工平行計算,每一個邏輯key都可以被獨立計算,相同的key的資料會被髮送到相同的並行任務中去處理。

Non-Keyed windows

通過使用windowAll來指定。原始的資料流不會被拆分成多個邏輯任務,所有視窗邏輯都是一個視窗任務來執行,所以並行度是1。

windows 生命週期

簡而言之,當第一個元素到達對應的視窗時,一個windows就會被開始建立。當時間(不管是event時間還是processing時間)達到時間戳範圍,就會移除視窗。另外,每一個視窗都有一個Trigger和window Functions,當資料到達視窗後,執行的函式就是window Functions,這個函式包含了對這個視窗內容的所有計算,當Trigger達到一定條件之後,就會觸發。

Windows Assigners

在指定流資料是否帶key之後,下一步就是定義視窗的分配器(windows assigner),windows assigner的職責是定義每一個傳入的元素如何分配到視窗內。對於keyby使用window()方法,對於non-keyby使用windowAll()方法。

WindowAssigner is responsible for assigning each incoming element to one or more windows. 

 每個傳入的資料分配給一個或多個視窗。

Flink內建的window assigner對於大多數場景來講基本上是夠用的(tumbling windows滾動視窗, sliding windows滑動視窗, session windows會話視窗 and global windows全域性視窗)。也可以通過繼承WindowAssigner來自定義一個window assigner。所有的內建window assigner(除了全域性視窗)都是基於時間(處理時間或事件時間)來分配資料的。

基於時間的視窗有一個開始的timestamp(inclusive)和結束timestamp(exclusive)表示視窗的大小。

Flink中對於視窗的劃分有兩大類,第一大類是基於time(用的最多),第二大類是基於count。