流式計算-窗口


 

前言

對於流式計算(streaming)而言,窗口是一個永遠繞不開的話題,最常見的需求,比如計算某個字段最近一小時的累積量,計算某個字段一天的出現的次數等。本篇文章針對流式計算的窗口模型(window model)進行深入解析。需要注意的是,本篇文章內容沒有考慮容錯問題,也就是默認本地內存中的數據不會丟失。

 

下面直奔主題,如果想更全面的了解流式計算和窗口模型,參考google大神的兩篇博客。

https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-101

https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-102

 

基礎窗口

通常情況下,我們理解窗口最多的是基於時間窗口,比如每過5分級計算某個字段的累積量,又或者是基於事件的窗口。而我認為,窗口應該是一個更廣義的模型。

在流式計算中,數據是沒有邊界的,源源不斷的數據從輸入流向輸出,但是計算是需要邊界的,無論是增量計算還是全量計算,都需要一個范圍。那么,把無限的數據流划分成一段一段的數據集,這個計算模型可以稱為窗口模型。

 

基本的窗口模型,會根據時間來划分出一個一個有范圍的窗口,在此基礎上對一批數據集進行計算。那么問題來了,划分窗口的時間從哪來呢。一般情況下,有兩種必定出現的時間,數據的發生時間(event time)和數據處理的時間(process time)。

這兩個時間怎么選擇呢,先來看一個例子,比如網頁中一個事件的觸發從而向后台提交了一條數據,后台把數據發到了kafka,另一端有一個kafka的消費者把數據取出來進行計算,那么數據發生時間就是該網頁事件觸發的時間,而數據處理時間則為最終計算這條數據的時刻。理想情況下,這兩個時間是成正比關系的,也就是數據發生的越晚,那么數據處理的越晚,但現實總是殘酷的,由於網絡波動,硬件設備故障等原因,數據總是會不按順序的被處理,參考圖1(來源於引用)。

 

圖1

在這個背景下,對時間的選擇顯得更加復雜。一般而言用的是數據產生的時間,更貼近業務的需求,所見即所得么,否則采用數據處理的時間會導致結果不穩定。

時間選擇問題暫時解決了,那么數據不是連續的情況下,怎么划分出窗口,比如你想象中每過1分鍾輸出一個窗口,然而數據在59秒之后再也沒有被接受直到幾分鍾之后。這顯然是不滿足需求的,所以,引入了watermark這個概念,個人認為翻譯為水位線比水印更好理解,水印這概念太抽象了。

watermark用於判定是否到達窗口的閾值,也就是產生一個窗口,watermark會不斷自我更新(說白了就是有個守護線程保證watermark不因為沒有數據而不增長)。當watermark到達窗口的閾值,那么小於watermark的數據會進入到該窗口。而watermark也分為基於數據產生時間或者數據處理時間得到。

基於數據產生時間,那么會導致窗口的觸發時間比理想慢很多,也就延遲大,因為數據是亂序進入的,需要等待直到數據的產生時間到達窗口閾值。

基於數據處理時間,那么會導致窗口內的數據缺失,理由有上面的差不多。

所以這就又引申出了另一個問題,這個問題可以通過觸發器(trigger)解決。所謂觸發器,其實就是根據不同的場景需求,給出最適合的窗口觸發要求,比如基於watermark的觸發器,基於事件的觸發器,基於會話的觸發器,更多參考streaming 102。觸發器又是另一個層面的東西了,和實際業務有關,就不再贅述。

窗口的划分問題解決了,那么數據的生命周期是不是也得再思考一下?數據從輸入到輸出,可能會經歷一個或者多個窗口,也可能由於延遲錯過所有的窗口,這就需要定義一個清晰的范圍來完整的給出數據的生命周期。這引入了一個新的概念lag,在‘watermark大於窗口結束時間+lag’這個前提下,該窗口滿足‘數據的時間小於watermark-lag’的數據可以被釋放,這個定義彌補了數據在生命周期管理的缺口。

 

高階窗口

基礎窗口介紹了窗口的基本思想和功能特性,可以滿足絕大部分需求。下面說說窗口的其他特性,聚合和撤銷(retracting)。

可能會出現這類需求,每次計算利用上一次計算后的結果,這樣既避免了重復計算,又減少了內存緩存。但在流式計算中會有個問題,每次窗口計算得到的聚合結果可能不是正確的,再完美的觸發器也會在某個窗口遺漏一些延遲數據,可能到下個窗口這些延遲的數據出現了,這就需要窗口支持撤銷功能,也就是修改上一個窗口的統計結果,然后把修改后的結果一起發送到下個窗口。這樣在下個窗口做統計的時候,就會修正之前錯誤的統計,並到達最優結果。

 

總結

批量計算其實是流式計算的一個子集,而窗口就是流式計算轉為批量計算的臨界點,所以這是及其重要的概念,另外更多的例子和實戰參考apache beam,一個高度抽象的統一編程模式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM