【大數據日記】【轉】The world beyond batch: Streaming 101(第二節)

數據處理模式

現在我們可以開始講一些有界和無界數據處理的重要模式了:批量和流式,這裏我把微批歸類爲流式,因爲二者的區別不是很重要。

有界數據

處理有界數據很簡單,大家都很熟悉。在下圖中,左邊是一個數據集,使用一些數據處理引擎對它進行處理(典型的是批量處理,儘管一個設計良好的流式引擎也可以勝任),例如 MapReduce,右邊則是處理後的結果:

enter image description here

圖2:使用一個典型的批量引擎處理有界數據。左邊的有限的無組織的數據通過數據處理引擎的處理,生成了右邊對應的結構化的數據。

有界數據處理整體來說是很簡單的,更讓我們感興趣的是如何處理無界數據。現在讓我們看看不同的處理無界數據的典型方法,首先會分析使用傳統的批量引擎的方法,然後分析像流式或者微批引擎這種爲無界數據設計的系統。

無界數據 – 批量

儘管批量引擎在大家的觀念中並不是爲無界數據處理設計的,但是從它誕生開始就被用來處理無界數據了。大家都能想到,只要我們把無界數據劃分成有界數據的集合,就可以採用批量處理。

固定窗口

使用批量引擎處理無界數據最常見的方法是將輸入數據切分到固定大小的窗口中,然後將每個窗口作爲獨立的有界數據進行處理。特別是像日誌這種輸入源,事件可以被寫進目錄和文件的層次結構中,它們對應的窗口被編碼進這些目錄文件的名字中,這種問題乍一看好像很簡單,因爲爲了將數據劃分到合適的 event time 窗口中,你已經執行了基於時間的 shuffle 操作。

然而實際上大部分系統需要處理完整性問題:如果一些事件由於網絡問題延遲到達怎麼辦?如果事件是從全球收集的,並且需要在處理前必須被髮送到一個公共位置怎麼辦?如果事件是來自移動設備的怎麼辦?這意味着可能需要一些特別的處理方法(例如延遲處理直到確定所有事件都已到達,或者只要有數據晚到就重新處理某個窗口的整個數據集)。

enter image description here

圖3:通過固定窗口使用典型的批量引擎處理無界數據。一個無界數據是有限的固定窗口的有界數據的集合,通過連續執行的批量引擎進行處理。

會話

當你使用像會話這種更精細的窗口策略,通過批量引擎處理無界數據時,會遇到更多的問題。會話一般是按活躍間隔劃分的(例如針對某個特定的用戶)。當使用典型的批量引擎計算會話時,經常會出現一個會話跨越多個分片,如下圖紅色標記部分。通過增加分片大小可以減少跨越多個分片的概率,但是會增加延遲。另一個方法是增加額外的邏輯來處理這種情況,代價是增加邏輯複雜度。

enter image description here

圖4:通過固定窗口使用典型的批量引擎處理無界數據。一個無界數據是有限的固定窗口的有界數據的集合,然後被細分成動態的會話窗口,通過連續執行的批量引擎進行處理。

這兩種方法都不夠完美,更好的方法是使用流式來處理會話,我們下面會講。

無界數據 – 流式

與大部分基於批量的無界數據處理方法不同,流式系統就是爲無界數據而設計的。正如上面所說,對於分佈式輸入源,它產生的數據不只是無界的,還具有如下特性:

  • 按 event times 無序,如果你想按發生的時間順序來分析數據,就需要基於時間進行 shuffle 處理。
  • event time skew 不確定,意味着你不能假設在 X+Y 時總是能看到大部分 event time 爲 X 的數據。

有一些處理具有這些特性的數據的方法。我大致將它們分爲4類:

  • 時間無關
  • 近似法
  • 基於 processing time 的時間窗口
  • 基於 event time 的時間窗口

我們對每一種方法進行分析。

時間無關

時間無關處理被用於不關心時間的場景中,也就是說所有的邏輯都是數據驅動的。由於這些場景的所有事情都是由到達的數據決定的,所以不需要流式引擎支持除了基本數據傳遞之外的特殊功能。目前所有的流式系統都能支持這種與時間無關的使用場景。批量系統也非常適合對無界數據進行這種時間無關的處理,只需要將無界數據劃分成任意長度的有界數據序列並分別獨立處理即可。我們將會舉幾個例子說明。

過濾

一個非常基本的時間無關處理的例子就是過濾。假設你在處理 Web 流量日誌,想要過濾出來自某個特定主域的流量。你會查看每條到達的日誌是否屬於那個主域,如果不是則丟棄。由於這件事在任何時刻都只依賴單條日誌,而數據源是無界的、無序的、以及 event time skew 是不確定的都沒有影響。

enter image description here

圖5:過濾無界數據。從左向右的流動的包含不同類型的數據被過濾成只包含一種類型的數據。

Inner-joins

另外一個時間無關的例子是 inner-join。當拼接兩個無界數據源時,如果你只關心拼接的結果,則處理邏輯不需要考慮時間的因素。一旦看到來自某個數據源的一個值,只需要把它緩存起來;當來自另一個數據源的第二個值到達時,則發送拼接結果即可。

enter image description here

圖6:對無界數據執行 inner join 操作。當來自兩個數據源的匹配的元素都到達時則產生拼接結果。

如果切換成 outer join 則會引入數據完備性問題:一旦看到了拼接的一邊,如何知道另一邊是否到達了呢?說實話,我們沒法得知,因此我們只能引入某種超時機制,這必然會引入時間因素。時間因素本質上就是時間窗口的形式,後面會更詳盡的介紹。

近似法

enter image description here

圖7:對無界數據計算近似值。數據經過一個複雜算法的處理,在另一邊生成與想要的結果近似的輸出數據。

第二大類方法就是近似算法,例如approximate Top-Nstreaming K-means 等等。它們以無界數據作爲輸入,並提供與你所希望獲得的結果類似的輸出數據。近似算法的優點是它們開銷很低並且天生就是爲處理無界數據而設計的。而缺點是它們的算法通常是很複雜的(這使得想出新的算法是很困難的),並且近似特性限制了它們的應用。

值得注意的是:這些算法在設計上通常都有一些時間因素。由於這些算法會隨着元素的到達而處理它們,時間因素通常都是基於 processing-time 的。這對於提供了某類可控錯誤邊界的算法是尤爲重要的。

近似算法本身是個很令人着迷的主題,但是因爲它們實質上是時間無關處理的另一種例子(除了算法本身的時間特徵),使用起來是很簡單的,所以就不再細說了。

 

文章轉自

http://coredumper.cn/index.php/2018/03/25/streaming-101-2/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章