Apache Flink 零基礎入門(五):流處理核心組件 Time&Window 深度解析

做者:邱從賢apache

1. Window & Time 介紹

Apache Flink(如下簡稱 Flink) 是一個自然支持無限流數據處理的分佈式計算框架,在 Flink 中 Window 能夠將無限流切分紅有限流,是處理有限流的核心組件,如今 Flink 中 Window 能夠是時間驅動的(Time Window),也能夠是數據驅動的(Count Window)。api

下面的代碼是在 Flink 中使用 Window 的兩個示例性能優化

1
2

2. Window API 使用

從第一部分咱們已經知道 Window 的一些基本概念,以及相關 API,下面咱們以一個實際例子來看看怎麼使用 Window 相關的 API。微信

代碼來自 flink-examples:網絡

3

上面的例子中咱們首先會對每條數據進行時間抽取,而後進行 keyby,接着依次調用 window(),evictor(), trigger() 以及 maxBy()。下面咱們重點來看 window(), evictor() 和 trigger() 這幾個方法。session

2.1 WindowAssigner, Evictor 以及 Trigger

Window 方法接收的輸入是一個WindowAssigner, WindowAssigner 負責將每條輸入的數據分發到正確的 Window 中(一條數據可能同時分發到多個 Window 中),Flink 提供了幾種通用的 WindowAssigner:tumbling window(窗口間的元素無重複),sliding window(窗口間的元素可能重複),session window 以及 global window。若是須要本身定製數據分發策略,則能夠實現一個 class,繼承自 WindowAssigner。框架

4

Tumbling Window機器學習

5

Sliding Window分佈式

6

Session Windowide

7

Global Window

Evictor 主要用於作一些數據的自定義操做,能夠在執行用戶代碼以前,也能夠在執行用戶代碼以後,更詳細的描述能夠參考 org.apache.flink.streaming.api.windowing.evictors.Evictor 的 evicBefore 和 evicAfter 兩個方法。Flink 提供了以下三種通用的 evictor:

  • CountEvictor 保留指定數量的元素

  • DeltaEvictor 經過執行用戶給定的 DeltaFunction 以及預設的 threshold,判斷是否刪除一個元素。

  • TimeEvictor設定一個閾值 interval,刪除全部再也不 max_ts - interval 範圍內的元素,其中 max_ts 是窗口內時間戳的最大值。

Evictor 是可選的方法,若是用戶不選擇,則默認沒有。

Trigger 用來判斷一個窗口是否須要被觸發,每一個 WindowAssigner 都自帶一個默認的 Trigger,若是默認的 Trigger 不能知足你的需求,則能夠自定義一個類,繼承自 Trigger 便可,咱們詳細描述下 Trigger 的接口以及含義:

  • onElement() 每次往 window 增長一個元素的時候都會觸發

  • onEventTime() 當 event-time timer 被觸發的時候會調用

  • onProcessingTime() 當 processing-time timer 被觸發的時候會調用

  • onMerge() 對兩個 trigger 的 state 進行 merge 操做

  • clear() window 銷燬的時候被調用

上面的接口中前三個會返回一個 TriggerResult,TriggerResult 有以下幾種可能的選擇:

  • CONTINUE 不作任何事情

  • FIRE 觸發 window

  • PURGE 清空整個 window 的元素並銷燬窗口

  • FIRE_AND_PURGE 觸發窗口,而後銷燬窗口

2.2 Time & Watermark

瞭解完上面的內容後,對於時間驅動的窗口,咱們還有兩個概念須要澄清:Time 和 Watermark。

咱們知道在分佈式環境中 Time 是一個很重要的概念,在 Flink 中 Time 能夠分爲三種 Event-Time,Processing-Time 以及 Ingestion-Time,三者的關係咱們能夠從下圖中得知:

8

Event Time、Ingestion Time、Processing Time

Event-Time 表示事件發生的時間,Processing-Time 則表示處理消息的時間(牆上時間),Ingestion-Time 表示進入到系統的時間。

在 Flink 中咱們能夠經過下面的方式進行 Time 類型的設置

env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime); // 設置使用 ProcessingTime

瞭解了 Time 以後,咱們還須要知道 Watermark 相關的概念。

咱們能夠考慮一個這樣的例子:某 App 會記錄用戶的全部點擊行爲,並回傳日誌(在網絡很差的狀況下,先保存在本地,延後回傳)。A 用戶在 11:02 對 App 進行操做,B 用戶在 11:03 操做了 App,可是 A 用戶的網絡不太穩定,回傳日誌延遲了,致使咱們在服務端先接受到 B 用戶 11:03 的消息,而後再接受到 A 用戶 11:02 的消息,消息亂序了。

那咱們怎麼保證基於 event-time 的窗口在銷燬的時候,已經處理完了全部的數據呢?這就是 watermark 的功能所在。watermark 會攜帶一個單調遞增的時間戳 t,watermark(t) 表示全部時間戳不大於 t 的數據都已經到來了,將來小於等於 t 的數據不會再來,所以能夠放心地觸發和銷燬窗口了。下圖中給了一個亂序數據流中的 Watermark 例子

9

2.3 遲到的數據

上面的 Watermark 讓咱們可以應對亂序的數據,可是真實世界中咱們無法獲得一個完美的 Watermark 數值 — 要麼無法獲取到,要麼耗費太大,所以實際工做中咱們會使用近似 watermark — 生成 watermark(t) 以後,還有較小的機率接受到時間戳 t 以前的數據,在 Flink 中將這些數據定義爲 「late elements」, 一樣咱們能夠在 Window 中指定是容許延遲的最大時間(默認爲 0),可使用下面的代碼進行設置

10

設置allowedLateness 以後,遲來的數據一樣能夠觸發窗口,進行輸出,利用 Flink 的 side output 機制,咱們能夠獲取到這些遲到的數據,使用方式以下:

11

須要注意的是,設置了 allowedLateness 以後,遲到的數據也可能觸發窗口,對於 Session window 來講,可能會對窗口進行合併,產生預期外的行爲。

3. Window 內部實現

在討論 Window 內部實現的時候,咱們再經過下圖回顧一下 Window 的生命週期

12

每條數據過來以後,會由 WindowAssigner 分配到對應的 Window,當 Window 被觸發以後,會交給 Evictor(若是沒有設置 Evictor 則跳過),而後處理 UserFunction。其中 WindowAssigner,Trigger,Evictor 咱們都在上面討論過,而 UserFunction 則是用戶編寫的代碼。

整個流程還有一個問題須要討論:Window 中的狀態存儲。咱們知道 Flink 是支持 Exactly Once 處理語義的,那麼 Window 中的狀態存儲和普通的狀態存儲又有什麼不同的地方呢?

首先給出具體的答案:從接口上能夠認爲沒有區別,可是每一個 Window 會屬於不一樣的 namespace,而非 Window 場景下,則都屬於 VoidNamespace ,最終由 State/Checkpoint 來保證數據的 Exactly Once 語義,下面咱們從 org.apache.flink.streaming.runtime.operators.windowing.WindowOperator 摘取一段代碼進行闡述

13

從上面咱們能夠知道,Window 中的的元素一樣是經過 State 進行維護,而後由 Checkpoint 機制保證 Exactly Once 語義。

至此,Time、Window 相關的全部內容都已經講解完畢,主要包括爲何要有 Window; Window 中的三個核心組件:WindowAssigner、Trigger 和 Evictor;Window 中怎麼處理亂序數據,亂序數據是否容許延遲,以及怎麼處理遲到的數據;最後咱們梳理了整個 Window 的數據流程,以及 Window 中怎麼保證 Exactly Once 語義。


▼ Apache Flink 社區推薦 ▼

Apache Flink 及大數據領域頂級盛會 Flink Forward Asia 2019 重磅開啓,目前正在徵集議題,限量早鳥票優惠ing。瞭解 Flink Forward Asia 2019 的更多信息,請查看:

developer.aliyun.com/special/ffa…

首屆 Apache Flink 極客挑戰賽重磅開啓,聚焦機器學習與性能優化兩大熱門領域,40萬獎金等你拿,加入挑戰請點擊:

tianchi.aliyun.com/markets/tia…

關注 Flink 官方社區微信公衆號,瞭解更多 Flink 資訊!

相關文章
相關標籤/搜索