Flink 时间语义与水位线(Watermarks)
文章目錄
- 時間語義
- 水位線(Watermarks)
時間語義
對于流式數據處理,最大的特點就是數據上具有時間的屬性特征,Flink根據時間產生的位置不同,將時間區分為如下三種時間概念
- 事件時間(Event Time):數據流事件實際發生的時間。
- 接入時間(Ingestion Time):數據進入Flink系統的時間。
- 處理時間(Processing Time):當前流處理算子所在機器上的本地時鐘時間。
Flink中 默認使用的是處理時間,但是在大多數情況下都會使用事件時間** (即實際事件的發生點,也符合事件發生進而分析的邏輯),一般只有在Event Time無法使用的情況下才會使用接入時間和處理時間,因此我們可以通過調用執行環境的setStreamTimeCharacteristic方法來指定時間語義
//創建執行環境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();//設置指定的時間語義,如下面的設置為EventTime env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);處理時間與事件時間的選擇
在大部分場景由于我們需要依據事件發生的順序來進行邏輯處理,因此都會使用事件時間。但是在一些特殊場景下,考慮到事件數據數據亂序到達以及延遲到達等問題,為了保證實時性和低延遲,處理時間就會派上用場。
例如下面幾種場景:
因此,對比處理時間和事件時間得出結論:
- 處理時間提供了低延遲,但是它的結果依賴處理速度,因此具有不確定性。
- 事件時間則與之相反,能夠保證結果的準確性,并允許你處理延遲甚至無序的事件。
水位線(Watermarks)
在理想狀態下,事件數據都是按照事件產生的時間順序傳輸至Flink系統中。但事實上,由于網絡或者分布式系統等外部因素的影響下,事件數據往往不能及時傳輸,導致系統的不穩定而造成數據亂序到達或者延遲到達等情況。
亂序數據的影響一旦出現這種問題,如果我們嚴格按照Event Time來決定窗口的運行,我們既不能保證屬于該窗口的數據已經全部到達,也不能無休止的等待延遲到達的數據,因此我們需要一種機制來控制數據處理的進度,這就是水位線(Watermarks)機制。
水位線是一個全局的進度指標,它能夠衡量數據處理進度 (表達數據到達的完整性),保證事件數據全部到達Flink系統,即使數據亂序或者延遲到達,也能夠像預期一樣計算出正確和連續的結果。
那么它是如何做到的呢?
- Flink會使用最新的事件時間減去固定時間間隔作為水位線,該時間時間為用戶外部配置的支持最大延遲到達的時間長度。
- 當一個算子接收到一個時間為T的水位線,就可以認為不會再收到任何時間戳小于或等于T的事件了(遲到事件或異常事件)
- 水位線其實就相當于一個提示算子的信號,當水位線時間戳大于時間窗口的結束時間,且窗口中含有事件數據時,此時算子就會認為某個特定時間區間的時間戳已經全部到齊,立即開始觸發窗口計算或對接收的數據進行排序。
從上面我們可以看出,水位線其實就是在結果的準確性和延遲之間做出取舍,它雖然保證了低延遲,但是伴隨而來的卻是低可信度。倘若我們要保證后續的延遲事件不丟失,就必須額外增加一些代碼來處理他們,但是如果采用這種保守的機制,雖然可信度低高了,但是延遲又會繼續增加,因此延遲和可信無法做到兩全其美,需要我們依據具體場景來自己平衡。
總結
以上是生活随笔為你收集整理的Flink 时间语义与水位线(Watermarks)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flink 架构:三层架构体系、运行时组
- 下一篇: Flink 状态管理:算子状态、键值分区