十一、Flink進階--Time深度解析

1. 概述

Flink在流處理程序中支持不同的時間概念。
在這裏插入圖片描述
首先需要理解三種time的含義:

  • Processing time: Processing time refers to the system time of the machine that is executing the respective operation. 處理事件時的時間,處理簡單,結果不確定
  • Event time: Event time is the time that each individual event occurred on its producing device. 事件產生的時間,處理複雜,結果確定可以重現
  • Ingestion time: Ingestion time is the time that events enter Flink. 事件進入Flink的時間

1.1設置一個時間特徵

首先定義你的流處理程序是已哪一種時間爲標誌的。

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

// env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime);
// env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

1.2EventTime 和 Watermark

在上述例子中爲了使用eventTime作爲時間處理標誌,必須在數據源中定義eventTIme並自動發出watermark或者程序在數據源定義之後注入一個TimeStamp Assigner 和 Watermark Generator 其中的一個。
在流處理程序中需要有一種方法能衡量數據處理的進度,例如統計每小時的窗口操作,需要在一小時後通知operator,並將窗口關閉。在flink中衡量event time進度的機制是watermark, watermark作爲數據流的一部分流動,並帶有時間戳,watermark t表示不會再有比t小的時間的數據到達,下圖展示了一個有序的流watermark
在這裏插入圖片描述
watermark對於無序流至關重要,因爲eventTime不按照時間戳排序,所以watermark聲明當前時間戳的時間都已到達,opeator會將其內部的時間提前到watermark的值。
在這裏插入圖片描述

2.TimeStamps/WaterMark

2.1TimeStamp的分配和WaterMark的生成

首先我們來看下TimeStamp的分配和WaterMark的生成,總共有2中方法:
1.在SourceFunction中產生,相當於將流的源頭定義

  • collectWithTimeStamp(T element, long timestamp) 參數:發送的數據,timestamp
  • emitWaterMark(WaterMark mark)

2.Time Assigner
在DataStream Api 流程中調用 DataStream.assignTimeStampsAndWaterMarks(),有2中具體的實現方法如下:

定期生成 根據特殊記錄生成
現實時間驅動 數據驅動
每隔一段時間調用生成 每一次分配TimeStamp都會調用方法
實現AssignerWithPeriodicWatermarks 實現AssignerWithPunctuatedWaterMarks

2.2 watermark傳播

watermark的傳播有以下幾個特點:

  • watermark以廣播的形式在算子之間傳播
  • 收到Long.MAX_VALUE表示不會再有數據收到,終止的意思
  • 單輸入流取最大的Watermark,多輸入的流取最小的watermark

watermark單個輸入取最大的,對於整個任務取最小的:

  • 對於同一個流,例如從kafka消費數據,多個partition,flink會進行強制的同步時鐘;
  • 但是對於不同流之間,join union操作,這時候快的流要等慢的流,這時候快的流就要在狀態中緩存很大的數據去等待慢的流,這是一個很大的資源消耗。

2.3 watermark的處理

在講watermark的處理之前,先講一下ProcessFunction,因爲watermark處理的外部邏輯是通過ProcessFunction來實現。ProcessFunction能實現時間相關的功能主要有三點:

  • 獲取記錄的TimeStamp 或 ProcTime
  • 獲取算子時間(或者理解爲獲取watermark時間)
  • 註冊Timer並提供回調邏輯
    • registerEventTimeTimer()
    • registerProcessingTimeTimer()
    • onTime() 處理邏輯
      所有的時間邏輯都是由TimeService來完成的

接下來看下當一個算子收到watermark時都要幹些什麼事情呢?
1.更新算子時間
2.遍歷計時器隊列觸發回調
3.將watermark發送到下游

這樣上述2.1-2.3就完成了watermark的生成到傳播到計算再到傳播,形成一個完整的閉環。

3.Table中時間

首先看一下ProcessingTime的在Table api和sql中的使用
ProcessingTime:

從DataStream轉化 通過TableSource生成
tEnv.fromDataStream(stream,“f1,f2,f3.proctime”) TableSource實現DefinedProcTimeAttributes接口

注意新加的processTime必須是最後一個字段

EventTime:

從DataStream轉化 通過TableSource生成
原始DataSteam必須有TimeStamp和watermark 數據中存在long或timestamp類型的字段
tEnv.fromDataStream(stream,“f1,f2,f3.rowtime”) TableSource實現DefinedRowTimeAttributes接口
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章