1. 程式人生 > >流式計算-low watermark機制

流式計算-low watermark機制

前言

最近在學習流式計算相關的知識,在閱讀了MillWheel論文,在這裡對low watermark機制做一個總結與介紹。

Window

實時資料流是永不停歇的,我們無法獲取所有的資料併產出一個最終的結果。很多情況下我們更關心的是最近的狀態,而不是從實時資料流啟動至今的統計資料。因此需要將資料流切分為一個個片段,這些片段形象的稱為Window。總而言之,Window是將無邊界的實時資料流進行劃分的一種機制。

Window大體分為三種:

  • Time Window:依靠時間作為劃分Window的依據,意思就是設立一個時間間隔來結束window,進行計算
    • Fixed Window:固定視窗,資料彼此不重疊
    • Sliding Window:滑動視窗,資料會重疊

這裡寫圖片描述

  • Session Window:依靠使用者的會話作為劃分Window的依據
    session window主要依靠設立的時間間隔來劃分一個window,即session gap。session window沒有具體的結束和開始時間,當一個window中超過session gap時間還沒有元素到來,該window就會結束並進行計算,此時就稱為一個會話。

這裡寫圖片描述

  • Global Window:將具有相同key的資料分配給同一個視窗,需要使用者自定義觸發器來進行計算,否則該window不會結束。

從中可以看出,Window的計算是非常依賴Time的。對於一個流式計算系統來說,Time分為兩類,選擇哪種作為劃分Window的標準更好,接下里我們就介紹兩種不同的Time。

Processing/Event Time

  • Processing Time:資料被處理的時間
  • Event Time:資料產生的時間
    這兩個概念很好理解,Processing Time就是指資料在流式計算中,不同PE對其進行處理的時間。而Event Time就是指資料產生的時間,比如使用者點選url的時間。

在流式計算早期,一般採用Processing Time作為Window劃分的時間,但是這樣有一個問題,當資料在上游延遲時,以Processing Time作為時間進行劃分Window,就會出現誤差。比如下圖中的例子:
這裡寫圖片描述

本來資料C在t3時刻產生,應當劃分進t1-t3這個Window,但是由於某些原因(網路延遲等),導致資料C在t7時刻才被處理。如果按照Processing Time進行處理,那麼C就落在了t4-tn的Window中,這很明顯會導致計算結果的不準確。比如我們需要統計在某個時間段使用者點選廣告的次數,如果按照Processing Time來算,那可能有些資料就會被劃分到其他window中,因此需要記錄Event Time,做法也很簡單,讓資料攜帶timestamp就行了。

使用了Event Time雖然可以讓資料落在正確的Window中,但是由於網路存在延遲以及各種原因,資料仍可能會遲到,如何才能讓Window儘可能等待這些會遲到的資料,這也是需要考慮的問題。最直觀的做法就是設定一個等待時間,但等待時間設定成多少合理,也需要考慮。為了解決這個問題,MillWheel論文中提出了lower watermark機制。

Timer

Timer即定時器,作為Window的觸發源,告知Window應當開始計算了。Timer分為兩類:

  • WallTime Timer:即按照正常的現實時間作為觸發源
  • LowWatermark Timer:以低水位作為觸發源

low watermark

low watermark其實就是一個時間戳,每個計算節點都會維護這樣一個時間戳作為low watermark。為了解決這類問題,MillWheel採用了Low Watermark機制,將lwm timer作為Window的觸發源。Low Watermark機制是流式系統中解決資料的完整性以及時效性問題的一種較好的方案,即為每個計算元件設立低水位值(時間戳),確保了不存在比當前時間戳還晚到達的資料,該機制的確保跟它的計算公式有關。

假設有計算節點A和C,並且C是A的上游節點,則A的低水位值的計算應該遵從以下公式。

low watermark of A = min (oldest work of A , low watermark of C : C outputs to A )
這裡寫圖片描述

從中可以看出,A的低水位值不只和A本身的最舊資料有關,也跟上游的低水位有關。因此,只要上游還有更舊的資料存在,就會通過低水位機制維護的low watermark告知下游,下游便會更新它自己的low watermark並且由於lwm timer未觸發,因此會進行等待。這樣就明顯形成了一個遞迴結構,low watermark的值與資料流的Injector有一定的關聯性。

該機制是怎樣解決這個問題的,這裡還是給出一個例子幫助大家理解。
這裡寫圖片描述
如圖所示,A的上游有C1-Cn各點,一直追溯到源頭Ij1-Ijn。A中維護了一個Window,用於統計9:30-10:00這半個小時的資料,而lwm timer為10:00,由於此時A的lwm為9:50,還沒有到lwm timer,因此Window不會關閉,會等待上游滯留的資料到達。lwm(A)之所以為9:50的原因是上游的資料有延遲,min(lwm of C1…Cn)=9:50。如果按照牆上時間10:30,此時早就應該觸發了,便會導致結果的不準確。

總結

關於流式計算的low watermark機制大概就是這樣,它可以在一定程度上保證資料的完整性以及時效性。但實際上,若就是有資料比low watermark還晚到達仍沒辦法解決,比如資料在沒有進入到流式計算系統之前就延誤了,那low watermark根本不得而知。Flink為了儘可能解決這種情況,除了low watermark還設定了allow lateness引數,即Window被lwm timer觸發後,還會等待allow lateness時間才開始計算,但這樣很明顯會損失一定的實時性。

由於每個流式計算系統的實現方式不一樣,MillWheel又將low watermark分為兩種watermark並且採用Server/Client中心化管理lwm,這裡就不展開了。