當前位置:
首頁 > 知識 > Apache Flink 數據流編程模型

Apache Flink 數據流編程模型

抽象等級(Levels of Abstraction)

Flink提供不同級別的抽象來開發流/批處理應用程序。

Apache Flink 數據流編程模型

Statefule Stream Processing: 是最低級別(底層)的抽象,只提供有狀態的流。它通過ProcessFunction嵌入到DataStream API之中。它使得用戶可以自由處理來源於一個或者多個流的事件

DataStream/DataSet API: 在我們的實際工作中,大多數的應用程序是不需要上文所描述的低級別(底層)抽象,而是相對於諸如DataStream API(有界/無界流)和DataSet API(有界數據集)的Core API進行編程。這些API提供了用於數據處理的通用模塊,如各種指定的transformations, joins, aggregations, windows, state等。在API中,這些處理的數據類型都是一個具體的實體類(class)。

底層的Process Function與DataStream API集成在一起,可以僅對一些操作進行底層抽象。

Table API: 是圍繞著table的申明性DSL,可以被動態的改變(當其表示流時)。Table API遵循(擴展)關係模型:表有一個模式鏈接(類似與在關係資料庫中的表),API也提供了一些類似的操作:select, project, join, group-by, aggregate等。Table API程序申明定義了怎麼做是規範的,而不是明確指定應該是什麼樣子的。雖然Table API可以通過各種類型的用戶定義的函數進行擴展,但它比Core API表達的更少,但使用起來更簡潔(少寫代碼)。另外,Table API程序也會通過一個優化器,在執行之前應用優化規則。

可以在表和DataStream / DataSet之間進行無縫轉換,允許程序混合使用Table API和DataStream 和DataSet API。

Flink提供的最高級抽象是SQL。 這種抽象在語義和表現力方面與Table API類似,但是將程序表示為SQL查詢表達式。在SQL抽象與Table API緊密地相互作用,另外,SQL查詢可以在Table API中定義的表上執行。

程序和數據流(Programs and Dataflows)

Flink可以說是由流(streams)和轉換(transformations)為基礎構建的(請注意,Flink的DataSet API中使用的數據集也是內部的流 )。從概念上講,流是數據記錄(可能是永無止境的)流,而轉換是將一個或多個流作為輸入,併產生一個或多個輸出流。

執行時,Flink程序被映射到由流和轉換運算符組成的流式數據流。每個數據從一個或多個源(sources)開始,並在一個或者多個接收器(sinks)中結束。數據流類似於一個任意有向無環圖(DAG)。儘管通過迭代構造允許特殊形式的循環,但是為了簡單起見,我們姑且先忽視這種情況。

Apache Flink 數據流編程模型

程序中的轉換與數據流中的操作符通常是一一對應的。然而,有時候,一個轉換可能由多個轉換操作符組成。

信號源(sources)和接收器(sinks)記錄在流式連接器和批量連接器文檔中。DataStream運算符和DataSet轉換中記錄了轉換。

並行數據流(Parallel Dataflows)

Flink中的程序本質上是並行和分布的。在執行過程中,一個流有一個或者多個流分區,每個運算符有一個或者多個子任務。操作符子任務彼此獨立,並且在不同的線程中執行,並且可能在不同的機器或容器上執行。

操作符子任務的數量是該特定操作符的並行度。流的並行性總是由生產它的操作符決定。同一個程序的不同運算符可能有不同的並行級別。

Apache Flink 數據流編程模型

流可以以一對一(One-to-one)或者重新分配(Redistributing)的模式在兩個操作符之間傳輸:

One-to-one: 保留了元素的分區和順序,如上圖中source —>map。這意味著map運算符的subtask[1]將按照源運算符的subtask[1]所產生順序相同。

Redistributing: 如上圖所示,map和keyBy/window之間,以及keyBy/window和Sink之間重新分配流,將會改變流的分區。每個操作符子任務根據所選的轉換將數據發送到不同的目標子任務。比如 keyBy()(其通過哈希重新分區),broadcast(), or rebalance() (其隨機重新分區)。在重新分配 交換中,元素之間的排序只保存在每對發送和接收的子任務中(例如map() 的subtask[1] 和 keyBy /window的subtask [2])。所以在這個例子里,每個關鍵字中的排序都被保留下來,但是並行性確實造成了不同關鍵字彙總結果後順序的非確定性。

有關配置和控制並行的細節可以在並行執行的文檔中找到。

窗口(Windows)

聚合事件(如:sum,count,etc)在流上的工作方式與批處理中的不同。例如,我們不能夠去統計流中的所有元素,因為流一般是無限的(無界的)。因而,流中的一些aggregate操作,是由Windows控制的,例如:計算過去五分鐘或者最後100個元素的總和。

Windows可以是由時間驅動的(例如,每30秒)或者數據驅動(例如每100個元素)。這可以用來區分不同類型的Windows,例如:tumbling windows (no overlap), sliding windows (with overlap), and session windows (punctuated by a gap of inactivity).

Apache Flink 數據流編程模型

更多的窗口示例可以在這篇博客文章中找到。更多細節在窗口文檔。

時間(Time)

當我們在流式編程中談及時間時,可以參考不同的時間概念:

Event Time, 是事件創建的時間,通常用時間戳表示。Flink通過時間戳分配器來訪問事件時間戳。

Ingestion time, 是事件進入Flink的時間,在源操作中每個記錄都會獲得源的當前時間作為時間戳,後續基於時間的操作(如: time window)會依賴這個時間戳

Processing Time, 是指each operator 執行程序時對應的物理機的系統時間

Apache Flink 數據流編程模型

有關如何處理時間的更多細節,請參閱event time 文檔。

有狀態的操作(Stateful Operations)

儘管數據流中很多操作看起來像一個單獨的事件,但是一些操作會跨越幾個事件記下相關的的信息(比如像window operators)。這種操作被稱為有狀態的(stateful)。

這種有狀態的操作,被保存在一種key/value的存儲結構之中。狀態與有狀態操作符讀取的流嚴格分區和分配。只有在keyed()函數之後才能訪問key/value狀態。並且僅限於與當前事件的鍵相關的值。流和狀態的keys的匹配保證了所有狀態更新都是本地操作,保證了一致性,所以不需要事務的開銷。這種匹配還允許flink重新分配狀態,並公開的調整分區。

Apache Flink 數據流編程模型

有關更多信息,請參閱有關狀態的文檔。

檢查點容錯(Checkpoints for Fault Tolerance)

Flink使用流重播(stream replay)檢查點(checkpointing) 的組合來實現容錯。檢查點與每個輸入流中的特定點以及每個操作元的相應狀態有關。數據流可以從檢查點恢復,同時保持一致性(exactly-once processing語義),方法是恢復operators 的狀態並從檢查點重放事件。

檢查點間隔是在執行恢復時間(需要被重放的事件的數量)的情況下折衷的容錯開銷手段。

容錯內部的描述提供了有關Flink如何管理檢查點和相關主題的更多信息。有關啟用和配置檢查點的詳細信息位於檢查點API文檔中。

批處理流(Batch on Streaming)

Flink執行批處理程序作為流程序的特殊情況,它是有限的(元素是有限的)。ADataSet 在內部視為數據流。因此,上述概念同樣適用於批處理程序,就像適用於流式處理程序一樣,但有一點例外:

  • 批處理程序的容錯不使用檢查點。通過完全重放流來恢復。這是可能的,因為輸入是有限的。這將成本更多推向recovery,但是使常規地處理更便宜,因為它避免了檢查點。
  • DataSet API中的有狀態操作使用簡化的內存/外核數據結構,而不是鍵/值索引。
  • DataSet API引入了特殊的同步(超級)iterations,這隻能在有界的流上進行。有關詳細信息,請查看iterations文檔。

作者:FlinkMe

原文:https://www.cnblogs.com/bigdata1024/p/10217015.html

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

python訓練mask rcnn模型&&C++調用訓練好的模型——基於opencv4.0
如何用dm-crypt加密Linux上的分區?

TAG:程序員小新人學習 |