[Flink] Flink的waterMark的通俗理解
阿新 • • 發佈:2020-03-31
### 導讀
Flink 為實時計算提供了三種時間,即**事件時間**(event time)、**攝入時間**(ingestion time)和**處理時間**(processing time)。
### 遇到的問題:
假設在一個5秒的Tumble視窗,有一個EventTime是 11秒的資料,在第16秒時候到來了。圖示第11秒的資料,在16秒到來了,如下圖:該如何處理遲到資料
![undefined](https://img2020.cnblogs.com/other/1473212/202003/1473212-20200331103734881-265570302.jpg)
### 什麼是Watermark
Watermark的關鍵點:
- 目的:處理EventTime 視窗計算
- 本質:時間戳
- 生成方式:Punctuated和Periodic(常用)
- 特性:單調遞增
### Watermark的產生方式
- Punctuated
資料流中每一個遞增的EventTime都會產生一個Watermark。
- Periodic(推薦)
週期性的(一定時間間隔或者達到一定的記錄條數)產生一個Watermark。
### Watermark解決的問題
上面的問題在於如何將遲來的EventTime 位11的元素正確處理?
當Watermark的時間戳等於Event中攜帶的EventTime時候,上面場景(Watermark=EventTime)的計算結果如下:
![undefined](https://img2020.cnblogs.com/other/1473212/202003/1473212-20200331103735324-1973364398.jpg)
如果想正確處理遲來的資料可以定義Watermark生成策略為 Watermark = EventTime -5s, 如下:
![undefined](https://img2020.cnblogs.com/other/1473212/202003/1473212-20200331103735659-185692784.jpg)
### WaterMark的例子
設定WaterMark步驟:
1.設定StreamTime Characteristic為Event Time,即設定流式時間視窗(也可以稱為流式時間特性)
2.建立的DataStreamSource呼叫assignTimestampsAndWatermarks方法,並設定WaterMark種類:AssignerWithPeriodicWatermarks / AssignerWithPunctuatedWatermarks
或者 實現AssignerWithPeriodicWatermarks介面 / 實現AssignerWithPunctuatedWatermarks介面
3.重寫getCurrentWatermark與extractTimestamp方法
getCurrentWatermark方法:獲取當前的水位線
extractTimestamp方法:提取資料流中的時間戳(必須顯式的指定資料中的Event Time)
**例項**
通過一段程式,實踐一下WaterMark的設定以及WaterMark的工作方式
**資料示例**:
key + 時間戳
```
hello,1553503210000
```
**程式說明**:
1.使用Socket模擬接收資料
2.設定WaterMark
設定的邏輯:在第一條資料進來時,設定WaterMark為0,指定第一條資料的時間戳後,獲取該時間戳與當前 WaterMark的最大值,並將最大值設定為下一條資料的WaterMark,以此類推
3.進行map基礎轉換,將String轉換為Tuple2