【Flink】核心概念

目錄

1、Dataflow Programming Model(Dataflow編程模型)

1.1、Levels of Abstraction(抽象層)

1.2、Programs and Dataflows(編程和數據流)

1.3、Parallel Dataflows(並行數據流圖)

1.4、Windows(窗口)

1.5、Time(時間)

1.6、Stateful Operations(有狀態操作)

1.7、Checkpoints for Fault Tolerance(檢查點容錯)

1.8、Batch on Streaming(流之上的批處理)

2、Distributed Runtime Environment

2.1、Tasks and Operator Chains(任務和操作鏈)

2.2、Job Managers, Task Managers, Clients(作業管理器,任務管理器,客戶端)

2.3、Task Slots and Resources

2.4、State Backends

2.5、Savepoints(存儲點)

1、Dataflow Programming Model(Dataflow編程模型)

1.1、Levels of Abstraction(抽象層)

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

  • 最底層的抽象接口是狀態化的數據流(stateful streaming)接口。這個接口是通過 Process Function嵌入到 DataStream API中。它允許用戶從一個或多個流中自由地處理事件,並使用一致性容錯狀態(state)。另外用戶可以註冊event time和processing time回調方法來實現複雜的計算。
  • 在實踐中,大部分應用程序不需要使用上面描述的底層的抽象功能,而是使用諸如DataStream API(有界/無界流)和DataSet API (有界數據集)這樣的CoreAPIs進行編程。這些核心API提供了大量的通用構建模塊(the common building blocks),比如各種用戶指定的transformation,join,aggregations,windows,state等。這些API的處理的數據類型被表示爲各自編程語言中類的形式。
  • 由於DataStream API集成了ProcessFunction,因此可以通過DataStream API爲某些特定操作應用底層處理接口。此外,DataSet API也爲諸如循環,迭代之類的有界數據集提供了一些補充的編程原語。
  • Table API 是一種以表爲核心的聲明式的DSL,它能夠動態變更表(在表示流時)。Table API遵循關係模型:表有一個Schema(類似於關係型數據庫中的表),並且API提供了類似的操作,比如select,project,join,groupby,aggregate等。Table API程序明確的定義了應該做什麼邏輯操作,而不是指定操作的代碼是什麼樣。雖然Table API可以通過各種用戶定義的函數進行擴展,但它的表達能力不如CoreAPI,但是使用起來更簡潔(編寫的代碼更少)。此外,TableAPI 程序在執行前通過優化器進行規則優化。
  • 你可以在tables和DataStream/DataSet之間無縫切換,允許程序將Table API和 DataStream、DataSetAPI混合在一起開發。
  • Flink提出的高級抽象是SQL。這個抽象類似於表達式和語義的Table API,將程序表示SQL查詢表達式。SQL抽象與Table API緊密的交互,SQL查詢可以在Table API 中定義的表上執行。

1.2、Programs and Dataflows(編程和數據流)

Flink的基本組成部分是streams和transformations。(請注意,Flink的DataSet API中使用數據集也在內部流中--後面有更多介紹)。從概念上說,stream是數據記錄流(可能是永不休止的),transformation是一種操作,它將一個或多個stream作爲輸入併產生一個或多個輸出流。

當執行時,Flink程序會映射爲Streaming dataflows,包括streams和transformation操作。每個dataflow開始於一個或多個sources,並以一個或多個sinks結束。dataflows類似於有向無環圖(DAG)。儘管通過迭代構造可以允許形成特殊的環,但爲了簡化說明,大部分情況下我們不考慮這種結構。

通常,程序中的轉換(transformation)和數據流圖(dataflow)中的操作符之間存在一對一的對應關係。然後,有時,一個轉換(transformation)可能由多個轉換操作符組成

Sources和sinks記錄在 streaming connectors and batch connectors文檔中,Transformation記錄在DataStream operators and DataSet transformations文檔中。

1.3、Parallel Dataflows(並行數據流圖)

Flink程序本質上是並行和分佈式的。在執行期間,一個stream有一個或多個 stream partitions(流分區),每個運算符有一個或多個operator subtasks(運算子任務)。運算子任務是彼此獨立的,並在不同的線程中執行,可能在不同的機器或container中執行。

運算子任務的數量是特定操作的併發度(parallelism )。stream的併發度通常是操作符產生的。同一個程序的不同操作符可能有不同級別的並行度。

A parallel dataflow

Stream可以通過一對一(forward)模式或重分佈式(redistributing)模式在兩個操作符之間傳輸數據。

  • 一對一的Stream(例如上圖中的Source和map()運算符之間的關係)保持了元素的分區和順序。這意味着map()的子任務map[1]將被同一順序下的同一元素看到,它們是由Source操作符的子任務Source[1]產生。(其實就是Spark的窄依賴)
  • 重分佈stream(在map()和keyBy/window之間,以及在keyBy/window和Sink之間)改變流的分區。每個操作子任務將數據發送到不同的目標子任務,這取決於選擇的transformation。上面例子的keyBy()(通過hash key重新分區),broadcast(),rebalance()(隨機重分區)。在分配交換中,元素之間的順序只保持在每對發送和接收的子任務中(例如,map()[1]子任務和 keyBy/window[2]子任務)。因此在這個例子中,每個排序的key可是被確定,但是並行度確實引入了關於不同key的聚合結果到達sink順序的不確定。(類似於Spark的寬依賴Shuffle操作)

1.4、Windows(窗口)

聚合事件(例如:count,sum)在流和批處理的工作方式是不同的。例如,不可能在一個流中count所有元素,因爲流通常是無限的(無界的)。相反,流的聚合(count,sum等)是由窗口作用的,例如“count最後五分鐘的數據”或者“最後100個元素求和”

Window可以是時間驅動的(每30秒)或者數據驅動的(每100個元素)。一個典型的區別是不同類型的窗口,例如滾動窗口(沒有重疊),滑動窗口(有重疊),回話窗口(中間有一個不活動的間隙)。

1.5、Time(時間)

當提到Streaming程序中的time(例如定義的window),可以引出不同的時間概念。

Event time: 是事件發生的時間,它通常由事件發生中的時間戳來描述,例如由生產傳感器或生產服務所創建的時間戳。Flink通過時間戳來訪問事件時間戳

Ingestion time:攝入時間是一個事件在source操作符中進入的Flink的時間

Processing time:處理時間是每個操作符基於時間操作的當前時間

• 一條日誌進入Flink的時間爲2017-11-12 10:00:00,123,到達window的系統時間爲2017-11-12 10:00:01,234.

日誌的內容如下:

• 2018-11-02 18:37:15,624 INFO org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider - Failing over to rm2

1.6、Stateful Operations(有狀態操作)

雖然dataflow中的很多操作符只是一次查看一個單獨的事件(如:事件解析器),但是某些操作會記住多個事件的信息(如窗口操作)。這些操作稱爲有狀態。

有狀態操作的狀態被維護在一個可以被認爲是嵌入key/value的存儲狀態中。狀態是分區的,並嚴格地與有狀態的操作讀取的流一起分發。因此,在keyBy函數之後,才能在keyed stream上訪問key/value的狀態,並且限制爲與當前事件key相關聯的值。對齊流和狀態的key,可確保所有狀態更新都是本地操作,從而保證一致性而無需事務開銷。這種對齊還允許Flink重新分配狀態並透明的調整流分區。

狀態分類:

  • Operator State(算子狀態)
  • Keyed State
  • State Backend (rocksdb + hdfs)

1.7、Checkpoints for Fault Tolerance(檢查點容錯)

Flink使用stream replay(流回放)和checkpointing(檢查點)的組合來實現容錯。checkpoint是與每個輸入流中的特定點以及每個操作符對應的狀態相關。通過恢復操作符的狀態,並從檢查的點重新播放事件,可以從檢查點恢復數據流,同時保持一致性(exactly-once處理語義)。檢查點間隔是一種在執行期間與恢復時間(需要重新回放的事件數量)執行容錯操作的方法。

• 輕量級容錯機制(全局異步,局部同步)

• 保證exactly-once 語義

• 用於內部失敗的恢復

• 基本原理:

通過往source 注入barrier

barrier作爲checkpoint的標誌

1.8、Batch on Streaming(流之上的批處理)

Flink將批處理(batch programs)程序作爲一種特殊的流程序,其中的流是有限的(有限的元素)。DataSet在內部被當做數據流來處理。上面的概念同樣適用於批處理程序,他們也適用於流處理,但也有列外:

  • 批處理的容錯能力不適用檢查點。恢復是通過完全重新回放流來實現的。因爲輸入是有界的。這是的成本更趨向於恢復,但是使常規的處理划算,因爲它避免了檢查點。
  • DataSet API中的 Stateful operations操作使用簡化的內存/非核心數據結構,而不是key/value索引。
  • DataSet API 引入了特殊的同步(基於超步)迭代,這隻在有界流上可行

2、Distributed Runtime Environment

2.1、Tasks and Operator Chains(任務和操作鏈)

對於分佈式執行,Flink將操作子任務鏈在一起爲任務(tasks)。每個task由一個線程執行。將操作鏈接到task是一種有用的優化:它減少了線程到線程的轉移和緩存,並且降低延遲的同時增加了總的吞吐量。操作鏈的配置 see the chaining docs for details.

下圖的實例dataflow以5個子任務執行,因此有5個並行線程。

2.2、Job Managers, Task Managers, Clients(作業管理器,任務管理器,客戶端)

Flink的運行時由兩種過程組成:

JobManagers(也叫masters)協調分佈式執行。它調度tasks,協調檢查點,協調故障恢復等等。至少有一個JobManager。高可用性設置將有多個JobManagers,其中一個始終是leader,而其他的是standby狀態

TaskManagers(也叫workders)執行一個dataflow的tasks(更具體是subtasks),並且進行緩存,交換數據流。必須至少有一個TaskManager

JobManager和TaskManager可以以不同的方式啓動:直接在機器上以 standalone cluster,container容器,或者資源管理器yarn或mesos的方式。TaskManager連接到JobManager,通知JobManager自己是可用的,並且可以被分配任務。

client不是程序執行的一部分,而是用來準備和發送一個dataflow到JobManager。然後,client可以斷開連接,或者保持連接以接收進度報告。client要麼觸發執行的Java/Scala程序,要麼在命令行過程中執行: ./bin/flink run ...

2.3、Task Slots and Resources

每個worker(TaskManager)是一個JVM進程,並且可以在單獨的線程中執行一個或多個子任務。爲了控制一個worker接收多個任務,一個worker又被稱爲task slots(至少有一個)。

每個task slots表示TaskManager的固定資源子集。例如,一個有3個slots的TaskManager將它的管理內存的1/3用於每個slot。對資源進行操作,意味着子任務將不會與其他作業的子任務的管理內存競爭,而是有一定數量的保留的管理內存。注意,這裏沒有CPU隔離,當前slots只分離任務的管理內存。通過調整任務的slots數量,用戶可以定義如何相互隔離子任務。每個TaskManager有一個slot意味着每個任務組運行在一個單獨的JVM中(例如,可以在一個單獨的容器中啓動)。擁有多個slots意味着更多的子任務共享同一個JVM。相同的JVM中任務共享TCP連接(通過多路複用)和心跳消息。他們還可以共享數據集合數據結構,從而減少每個任務的開銷。

在默認情況下,Flink允許子任務共享slot,即使它們是不同任務的子任務,只要它們來自同一個job。其結果是,一個slot能夠容納整個工作流程。允許這種共享slot有兩個主要的好處:

  • Flink集羣需要的task slots與job的最高並行度一樣。不需要計算一個程序總共包含多少個任務(有不同的並行度)。
  • 它更容易獲得更好的資源利用。如果沒有slot共享,非密集型的source/map()子任務將會阻塞與資源密集型的window子任務一樣多的資源。使用共享slot,將實例中的基本並行度從2個增加到6個,從而充分利用有slot的資源,同時確保重子任務在TaskManager中是公平分配的。

這些API也包含了資源組(resource group )的機制,可用於防止不受歡迎的slot共享。

作爲一個經驗法則,一個好的默認數量的任務slot是CPU core的數量,對於超線程,每個slot都需要2個或更多的硬件線程上下文。

2.4、State Backends

ey/value索引存儲的確切的數據結構依賴於所選的 state backend。一種state backend 將數據存儲在內存中的hash map中,另一種state backend 使用RocksDB作爲key/value存儲。除了定義保存狀態的數據結構外,state backend還實現以獲取key/value的時間點快照邏輯,並將該快照作爲檢查點的一部分存儲。

2.5、Savepoints(存儲點)

在DataStream API中編寫的程序可以從保存點恢復執行。savepoints 允許更新你的程序和Flink集羣,而不會失去任何狀態。

Savepoints是手動觸發的檢查點,它會對程序進行快照,並將其寫入到一個state backend。它們依賴於常規的檢查點機制。在執行程序期間,週期性地在工作節點上快照並生成檢查點。對於恢復來說,只有最後一個完成的檢查點是需要的,並且舊的檢查點可以在新的完成之後被安全的丟棄。

Savepoints類似於週期性檢查點,但它們是由用戶觸發的,當更新的檢查點完成時不會自動過期。可以從命令行創建保存點,也可以通過REST API取消作業。

• 流處理過程中的狀態歷史版本

• 具有可以replay的功能

• 外部恢復(應用重啓和升級)

• 兩種方式觸發

• Cancel with savepoint

• 手動主動觸發

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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