Flink-2-流處理基礎

第2章 流處理基礎

參考書籍編程

注:本文主要是針對《基於Apache Flink的流處理》的筆記服務器

1-8章筆記下載地址網絡

本章的目標是介紹流處理的基本概念以及對其處理框架的要求。session

2.1 Dataflow編程概述

2.1.1 Dataflow圖

Dataflow程序一般表示爲有向圖併發

  • 其中節點稱爲算子,表明計算,表明數據依賴
  • 算子數據流應用程序基本功能單元。它們從輸入中獲取數據,對數據進行計算,而後將數據輸出到輸出端進行進一步處理。
  • 沒有輸入端的算子稱爲數據源沒有輸出端的算子稱爲數據匯
  • 數據流圖必須至少一個數據源一個數據匯

圖2-1顯示了一個數據流程序,它從文章的輸入流中提取並計數一些標籤。app

image-20201029121349342

像圖2-1中的數據流圖被稱爲邏輯圖,由於它們傳達了計算邏輯的高級視圖。爲了執行數據流程序,它的邏輯圖被轉換成物理Dataflow圖,該圖詳細說明了程序是如何執行的。例如,若是咱們使用分佈式處理引擎,每一個 算子可能有幾個並行任務在不一樣的物理機器上運行。負載均衡

圖2-2顯示了圖2-1的邏輯圖的物理數據流圖。在邏輯Dataflow圖中,節點表明算子,而在物理Dataflow圖中,節點表明任務。每一個任務負責計算一部分的輸入數據。框架

2.1.2 數據並行和任務並行

能夠以不一樣的方式利用數據流圖中的並行性。

首先,能夠對某個算子輸入數據進行分區,並在數據子集並行執行相同操做的任務。這種類型的並行稱爲數據並行。數據並行很是有用,由於它容許將大量計算數據分佈到多個不一樣的物理節點上並行執行。

其次,可讓不一樣算子任務 並行執行相同或不一樣數據的計算。這種類型的並行稱爲任務並行。使用任務並行,能夠更好地利用集羣的計算資源。

2.1.3 數據交換策略

數據交換策略定義了數據項如何被分配給物理Dataflow圖中的不一樣任務。在這裏,咱們簡要介紹一些常見的數據交換策略,如圖2-3所示。

  • 轉發策略發送端任務接收端任務之間一對一地進行數據傳輸。若是兩個任務位於同一個物理機器上(這一般由任務調度器來保證),這種交換策略避免了網絡通訊。
  • 廣播策略每一個數據項發送給算子的全部並行任務。由於這種策略複製數據並涉及網絡通訊,因此成本至關高。
  • 基於鍵值的策略經過鍵屬性劃分數據,並保證具備相同鍵的數據項由相同的任務處理
  • 隨機策略將數據項均勻隨機分配給任務,以便負載均衡

2.2 並行流處理

下面看看如何將Dataflow的概念運用到並行數據流處理中。咱們先給出數據流的定義:數據流是一個長度可能無限長的事件序列

數據流的例子以下:監控器產生的監控數據、傳感器產生的測量數據、信用卡交易數據、氣象站觀測數據、搜索引擎搜索記錄等

2.2.1 延遲和吞吐

對於批處理應用程序,咱們一般關心做業的總執行時間,或者咱們的處理引擎讀取輸入、執行計算和寫回結果須要多長時間。因爲流應用程序連續運行,而且輸入多是無限的,所以在流處理沒有總執行時間的概念。取而代之的是,流處理必須儘量地爲傳入數據提供結果(延遲),同時還要應對很高的事件輸入速率(吞吐)。咱們用延遲和吞吐來表示這兩方面的性能需求。

2.2.1.1 延遲

延遲表示處理一個事件所需的時間。本質上,它是接收事件到在輸出中看到事件處理效果的時間間隔。

在數據流中,延遲以時間爲單位進行衡量,例如毫秒。根據應用程序的不一樣,可能會關心平均延遲最大延遲百分比延遲。例如,10ms的平均延遲意味着平均在10ms內處理事件。或者,10毫秒的95%延遲值意味着95%的事件在10毫秒內獲得處理。

像Apache Flink這樣的現代流處理引擎能夠提供低至幾毫秒的延遲。

2.2.1.2 吞吐

吞吐量是對系統處理能力的一種度量——它的處理速率。也就是說,吞吐量告訴咱們系統每單位時間能夠處理多少個事件

須要注意的是,處理的速率取決於事件到達速率;低吞吐量不必定表示性能差。在流式系統中,一般但願確保系統可以處理最大的預期事件到達速率。也就是說,主要關心的是肯定峯值吞吐量,即系統處於最大負載時的性能限制。

一旦事件到達速率超過了預期的最大值,咱們就不得不開始緩衝事件。若是系統繼續以超過其處理能力的接收速率接收數據,緩衝區可能會變得不可用,數據可能會丟失。這種狀況一般被稱爲背壓

2.2.1.3 延遲與吞吐

此時,應該清楚的是,延遲吞吐 不是獨立的指標

  • 若是事件須要很長時間才能在數據處理管道中傳輸,咱們就沒法輕鬆確保高吞吐量(延遲影響了吞吐)。
  • 一樣,若是系統的處理能力太低,事件將被緩衝,必須等待才能獲得處理(吞吐影響了延遲)。

下降延遲可提升吞吐量。若是一個系統能夠更快地執行操做,它能夠在相同的時間內執行更多的操做。而一個很好的方式就是並行處理

2.2.2 數據流上的操做

流處理引擎一般提供一組內置操做來接收、轉換和輸出數據流。這些操做能夠用來構成Dataflow圖表明流式應用的邏輯。在本節中,咱們將介紹最常見的流式操做

操做能夠是無狀態的,也能夠是有狀態的。

  • 無狀態操做不維護任何內部狀態。也就是說,一個事件的處理 不依賴於 任何歷史事件,也不保留歷史數據。無狀態操做很容易並行化
  • 有狀態操做會維護他們之前接收到的事件的信息狀態經過傳入的事件更新,而且在將來事件處理邏輯中使用。有狀態流處理應用程序在並行化容錯方面更具挑戰性
2.2.2.1 數據接入和數據輸出

數據接入和數據輸出操做容許流處理器與外部系統通訊。

數據接入是從外部系統 獲取原始數據並將其轉換爲適合處理格式的操做。實現數據接入邏輯算子稱爲數據源

數據輸出是以適合外部系統使用的形式產生輸出的操做。實現數據輸出算子稱爲數據匯

2.2.2.2 轉換操做

轉換操做是單程操做(single-pass),每一個事件獨立處理。操做一個接一個處理事件,並對事件數據進行一些轉換,產生一個新的輸出流。通常來講,轉換操做比較簡單,不用維護內部狀態

轉換操做的算子能夠接受多個輸入併產生多個輸出流。他們還能夠經過將一個流分紅多個流或將多個流合併成一個流來修改數據流圖的結構。

2.2.2.3 滾動聚合

滾動聚合是針對每一個輸入事件不斷更新聚合操做,好比總和最小值最大值聚合操做有狀態的,並將當前狀態傳入事件相結合生成新的聚合值。圖2-5顯示了一個滾動最小聚合。操做符保持當前的最小值,並針對每一個傳入事件相應地更新它。

2.2.2.4 窗口操做

轉換滾動聚合 每次處理一個事件,以生成輸出事件並更新狀態。可是,有些操做必須收集緩存事件。例如求中位數的函數。爲了在無限流高效地計算這些操做,須要限制這些操做維護的數據量。在本節中,咱們將討論窗口操做

窗口還支持在數據流進行一些有趣的查詢。例如:若是有一個爲司機提供實時交通訊息的應用程序。在這個場景中,您想知道在過去幾分鐘內某個位置是否發生了擁堵。這時候咱們只關注過去幾分鐘這個窗口的數據。

窗口操做不斷地從一個無界事件流建立 長度有限的事件集(稱爲),並讓咱們對這些 執行計算。事件一般根據數據屬性或時間分配到桶中。窗口的行爲一組策略定義窗口策略決定什麼時候建立新的存儲桶,將哪些事件分配給哪些存儲桶,以及什麼時候計算桶中的數據。窗口策略指定能夠基於時間數量其餘數據屬性

下面介紹常見的窗口類型的語義

2.2.2.4.1 滾動窗口

滾動窗口事件分配長度固定不重疊的桶中。當窗口邊界經過時,全部事件都被發送到一個計算函數進行處理。基於計數的滾動窗口定義了在觸發評估以前收集了多少事件。圖2-6顯示了一個基於計數的滾動窗口,它將輸入流分到四個元素組成的桶。基於時間的滾動窗口定義了桶中事件的時間間隔。圖2-7顯示了一個基於時間的滾動窗口,它將事件收集到桶中,並每10分鐘觸發一次計算。

2.2.2.4.2 滑動窗口

滑動窗口將事件分配到固定大小容許互相重疊的桶中。所以,一個事件 可能屬於多個桶。咱們經過指定桶的長度滑動間隔來定義滑動窗口。圖2-8中的窗口長度爲4,滑動間隔爲3。

2.2.2.4.3 會話窗口

會話窗口在常見的現實場景中很是有用,在這些場景中,滾動窗口和滑動窗口都不能應用。考慮一個分析在線用戶行爲的應用程序。在這樣的應用程序中,咱們但願未來自同一會話事件分到一組

會話窗口根據會話間隔(session gap)對事件進行分組,會話間隔定義了認爲會話已關閉的非活動時間。(也就是若是用戶在很長的一段時間內沒有與服務器通訊就認爲他的會話已經關閉了)

窗口操做與流處理中的兩個主要概念密切相關:時間語義狀態管理

  • 流數據一般會有延遲或者亂序到達,這時如何保證窗口正確劃分就很重要
  • 此外,爲了不故障,須要在生成結果以前將窗口中的數據都採起安全措施保護起來

2.3 時間語義

2.3.2 處理時間

處理時間機器本地時鐘的時間。處理時間窗口包括在一段時間內** 碰巧到達窗口全部事件,由機器的本地時鐘測量。如圖2-12所示

2.3.3 事件時間

事件時間是流中的事件實際發生時間。事件時間經過附加到流事件時間戳來判斷。

圖2-13顯示:即便事件有延遲,事件時間窗口也能準確地把事件分配到正確的窗口中,從而反映事情發生的真實狀況

不管數據流的處理速度有多快,事件到達算子的順序是怎樣的,事件時間窗口的計算將產生相同的結果。

經過依賴事件時間,即便是在無序數據的狀況下,咱們也能夠保證結果的正確性。此外,當與可重放的流結合時,時間戳的肯定性使你可以回到過去。也就是說,你能夠重放一個流並分析歷史數據,就像事件是實時發生的同樣。

2.3.4 水位線

到目前爲止,在咱們關於事件時間窗口的討論中,咱們忽略了一個很是重要的方面:咱們如何決定事件時間窗口觸發時機(何時中止收集並開始計算)?也就是說,咱們要等多久才能肯定咱們已經收到了某個時間點以前發生的全部事件?考慮到分佈式系統的不可預測性和由外部帶來的各類延遲,這些問題沒有絕對正確的答案

水位線(watermark)是一種全局進度度量,它是一個時間點。它代表咱們確信這個時間點以前的事件所有到達了。本質上,水位線提供了一個邏輯時鐘,通知系統當前的事件時間。當操做員收到時間爲T的水位線時,能夠假設不會再收到時間戳小於T的事件。水位線對於事件時間窗口和處理無序事件的算子都是必不可少的。

水位線提供告終果可信度和延遲之間trade-off

  • 激進的水位線確保低延遲,但提供較低可信度
  • 保守的水位線帶來高延遲,但同時帶來較高可信度

流處理系統會提供某種機制處理水位線以後到達的事件。

2.3.5 處理時間與事件時間

此刻你可能會想,既然事件時間解決了咱們全部的問題,爲何咱們還要去關心處理時間?

事實是,在某些狀況下,處理時間確實頗有用。

  • 處理時間窗口引入了儘量低的延遲
  • 當你須要按期實時報告結果時,可是不太關注結果的精度時,處理時間是更合適的。
  • 最後,處理時間窗口提供了流自己的真實狀況,這對於一些用例來講多是一個理想的屬性。

2.4 狀態和一致性模型

狀態在數據處理中無處不在。任何複雜一點的計算都須要它。爲了產生結果,函數在一段時間或多個事件上累積狀態(例如,計算彙集或檢測模式)。有狀態算子使用傳入事件內部狀態計算它們的輸出更新狀態

在連續運行的流做業中,狀態在事件之間是持久的,咱們能夠在編程模型中將其做爲一級公民公開。而在以前的批處理中,後一個批次的數據是看不到前一個批次的數據的。

因爲流操做引擎有可能處理的是無限流,所以應當心不要讓內部狀態無限增加。爲了限制狀態的大小,算子一般會對到目前爲止看到的事件進行某種總結概要。這樣的摘要能夠是計數總和、迄今爲止所看到的事件的抽樣窗口緩衝區。

支持有狀態算子會帶來不少實現上的挑戰:

  1. 狀態管理:系統須要有效地管理狀態,並確保它不受併發更新的影響
  2. 狀態劃分:並行化變得複雜,由於結果取決於狀態和傳入的事件。幸運的是,在許多狀況下,您能夠經過一個鍵來劃分狀態,並獨立管理每一個分區的狀態。例如,好比正在處理來自一組傳感器的測量流,能夠用不一樣的分區來處理不一樣的傳感器。
  3. 狀態恢復:有狀態操做符帶來的第三個也是最大的挑戰是確保狀態能夠恢復,而且即便在出現故障的狀況下結果也是正確的。

2.4.1 任務故障

流式做業中的算子狀態很是重要,應防止出現故障。若是狀態在故障期間丟失,恢復後的結果將是不正確的。流處理引擎不只須要保證在出現任務故障時能夠正常運行,還須要保證結果和算子狀態的正確性。

對於輸入流中的每一個事件,任務執行如下步驟:

  1. 接收事件,將其存儲在本地緩衝區中;
  2. 更新內部狀態
  3. 產生輸出記錄。

在這些步驟中的任何一個均可能發生故障,系統必須清楚地定義其在每種故障場景中的如何處理。例如,一個定義完整的流式處理系統須要明確如下問題:若是任務在第一步失敗,事件會丟失嗎?若是在更新了內部狀態後失敗了,恢復後還會再更新嗎?而在上面這些狀況下,輸出仍是正確的嗎?

2.4.2 結果保障

在批處理場景中,全部這些問題都獲得了回答,由於批處理做業能夠簡單地從頭開始從新啓動。所以,沒有事件丟失,狀態徹底是從零開始創建的。然而,在流處理中,這些問題很棘手。流式系統經過提供結果保障(result guarantee)來定義它們在出現故障時的行爲。接下來,咱們回顧了現代流處理引擎提供的幾種不一樣級別的結果保障。

2.4.2.1 至多一次(AT-MOST-ONCE)

當任務失敗時,最簡單的方法就是不作任何事情來恢復丟失的狀態和重放丟失的事件。至多一次只保證每一個事件至多處理一次。換句話說,系統能夠簡單地丟棄事件,不作任何事情來確保結果的正確性。這種類型的保障也被稱爲「無保障」,由於即便是系統丟棄全部事件也能夠提供這種保證。

2.4.2.2 至少一次(AT-LEAST-ONCE)

在大多數現實世界的應用程序中,人們指望事件不會丟失。這種類型的保證被稱爲至少一次這意味着全部事件都將被處理,而且其中一些事件有可能被處理屢次。若是應用程序的正確性僅取決於信息的完整性,重複處理多是能夠接受的。

爲了確保至少一次這種結果保障,須要有一種方法來重放(replay)事件——要麼從源(source),要麼從某個緩衝區(buffer)。

下面介紹兩種保證至少一次的方式

  1. 持久事件日誌將全部事件寫入持久存儲,以便在任務失敗時能夠重放(replay)。
  2. 另外一種方法是使用記錄確認。此方法將每一個事件存儲在緩衝區中,直到管道中的全部任務都確認這個事件已經處理過了,此時能夠丟棄該事件。
2.4.2.3 精確一次(EXACTLY-ONCE)

精確一次是最嚴格的保證,也很難實現。它意味着不只不會有事件丟失,並且每一個事件只容許處理一次。從本質上來講,精確一次意味着咱們的應用程序將提供徹底正確的結果,就好像從未發生過失敗同樣

精確一次以致少一次爲前提的,所以數據重放機制必不可少。

並且在故障恢復以後,處理引擎應該知道一個事件的更新是否已經反映在狀態上。有兩種實現方式:

  • 事務性更新是實現這一結果的一種方式,可是它們會致使大量的性能開銷。

  • 相反,Flink使用輕量級快照機制來實現一次結果保證

2.4.2.4 端到端精確一次(END-TO-END EXACTLY-ONCE)

端到端保證指的是整個數據處理流水線上的結果正確性。流水線上的每一個組件都提供本身的保證,完整管道的端到端保證將由全部組件中最弱的那個組件來決定。有時候弱的保障可能會表現出強的語義,好比,你使用至少一次來求最大值或者最小值,管道的其餘組件都使用精確一次,那麼這個管道也是端到端精確一次的。

相關文章
相關標籤/搜索