讀《Flink基礎教程》02 流處理架構
Flink 專案的架構有兩個主要組成部分:訊息傳輸層和由 Flink 提供的流處理層。訊息傳輸層負責傳輸連續事件產生的訊息,能夠提供訊息傳輸的系統包括 Kafka 和 MapR Streams。
對時間的處理
採用批處理架構
用定期執行的批處理作業來實現應用程式的持續性。資料被持續地分割為檔案(如以一小時為單位);然後,批處理作業將檔案作為輸入,以此達到持續處理資料的效果。
採用流處理架構計數
通過流處理架構實現應用程式的持續性。水平圓柱體表示訊息傳輸系統(Kafka 或 MapR Streams)。訊息傳輸系統為負責處理所有資料的流處理器(在本例中是 Flink)提供流資料。
DataStream<LogEvent> stream = env // 通過Kafka生成資料流 .addSource(new FlinkKafkaConsumer(...)) // 分組 .keyBy("country") // 將時間視窗設為60分鐘 .timeWindow(Time.minutes(60)) // 針對每個時間視窗進行操作 .apply(new CountPerWindowFunction());
流處理區別於批處理最主要的兩點是:流即是流,不必人為地將它分割為檔案;時間的定義被明確地寫入應用程式程式碼(如以上程式碼的時間視窗),而不是與攝取、計算和排程等過程牽扯不清。
時間概念
在流處理中,主要有兩個時間概念:
-
事件時間,即事件實際發生的時間。
-
處理時間,即事件被處理的時間。處理時間其實就是處理事件的機器所測量的時間。
還有第 3 個時間概念,即攝取時間,也叫作進入時間。它指的是事件進入流處理框架的時間。缺乏真實事件時間的資料會被流處理器附上時間戳,即流處理器第一次看到它的時間。
視窗
視窗是一種機制,它用於將許多事件按照時間或者其他特徵分組,從而將每一組作為整體進行分析(比如求和)。
時間視窗
時間視窗是最簡單和最有用的一種視窗。它支援滾動和滑動。
一分鐘滾動視窗計算最近一分鐘的數值總和。在 Flink 中,定義如下:
stream.timeWindow(Time.minutes(1))
一分鐘滑動視窗每半分鐘計算一次最近一分鐘的數值總和。在 Flink 中,定義如下:
stream.timeWindow(Time.minutes(1), Time.seconds(30))
計數視窗
Flink 支援的另一種常見視窗叫作計數視窗。採用計數視窗時,分組依據不再是時間戳,而是元素的數量。滾動和滑動的計數視窗分別定義如下。
stream.countWindow(4) stream.countWindow(4, 2)
假設計數視窗定義的元素數量為 100,而某個 key 對應的元素永遠達不到 100 個,那麼視窗就永遠不會關閉,被該窗口占用的記憶體也就浪費了。
時空穿梭
流處理架構的一個核心能力是時空穿梭。
時空穿梭意味著將資料流倒回至過去的某個時間,重新啟動處理程式,直到處理至當前時間為止。
流處理架構擁有時空穿梭(即重新處理資料)的能力。流處理器支援事件時間,這意味著將資料流“倒帶”,用同一組資料重新運行同樣的程式,會得到相同的結果。
水印
Flink 通過水印來推進事件時間。水印是嵌在流中的常規記錄,計算程式通過水印獲知某個時間點已到。水印使事件時間與處理時間完全無關。