1. 程式人生 > 其它 >Flink:執行時架構

Flink:執行時架構

Flink四大元件

作業管理器(JobManager)

• 控制一個應用程式執行的主程序,也就是說,每個應用程式都會被一個不同的 JobManager 所控制執行。

• JobManager 會先接收到要執行的應用程式,這個應用程式會包括:作業圖 (JobGraph)、邏輯資料流圖(logical dataflow graph)和打包了所有的類、 庫和其它資源的JAR包。

• JobManager 會把JobGraph轉換成一個物理層面的資料流圖,這個圖被叫做 “執行圖”(ExecutionGraph),包含了所有可以併發執行的任務。

• JobManager 會向資源管理器(ResourceManager)請求執行任務必要的資源, 也就是工作管理員(TaskManager)上的插槽(slot)。一旦它獲取到了足夠的 資源,就會將執行圖分發到真正執行它們的TaskManager上。而在執行過程中, JobManager會負責所有需要中央協調的操作,比如說檢查點(checkpoints) 的協調。

工作管理員(TaskManager)

• Flink中的工作程序。通常在Flink中會有多個TaskManager執行,每一 個TaskManager都包含了一定數量的插槽(slots)。插槽的數量限制 了TaskManager能夠執行的任務數量。

• 啟動之後,TaskManager會向資源管理器註冊它的插槽;收到資源管理 器的指令後,TaskManager就會將一個或者多個插槽提供給 JobManager呼叫。JobManager就可以向插槽分配任務(tasks)來 執行了。

• 在執行過程中,一個TaskManager可以跟其它運行同一應用程式的 TaskManager交換資料。

資源管理器(ResourceManager)

• 主要負責管理工作管理員(TaskManager)的插槽(slot), TaskManger 插槽是Flink中定義的處理資源單元。

• Flink為不同的環境和資源管理工具提供了不同資源管理器,比如YARN、 Mesos、K8s,以及standalone部署。

• 當JobManager申請插槽資源時,ResourceManager會將有空閒插槽 的TaskManager分配給JobManager。如果ResourceManager沒有足 夠的插槽來滿足JobManager的請求,它還可以向資源提供平臺發起會 話,以提供啟動TaskManager程序的容器。

分發器(Dispatcher)

• 可以跨作業執行,它為應用提交提供了REST介面。

• 當一個應用被提交執行時,分發器就會啟動並將應用移交給一個 JobManager。

• Dispatcher也會啟動一個Web UI,用來方便地展示和監控作業 執行的資訊。

• Dispatcher在架構中可能並不是必需的,這取決於應用提交執行 的方式。

任務提交流程

任務提交流程(Yarn)

任務排程原理

Slot和任務排程

並行度(Parallelism)

一個特定運算元的子任務(subtask)的個數被稱之為其並行度(parallelism)。

一般情況下,一個stream 的並行度,可以認為就是其所有運算元中最大的並行度。

TaskManager 和 Slots

Flink 中每一個 TaskManager 都是一個JVM程序,它可能會在獨立的執行緒上執 行一個或多個子任務

為了控制一個 TaskManager 能接收多少個 task, TaskManager 通過 task slot 來進行控制(一個 TaskManager 至少有一個 slot)

預設情況下,Flink 允許子任務共享 slot,即使它們是不同任務的子任務。 這樣 的結果是,一個 slot 可以儲存作業的整個管道。

Task Slot 是靜態的概念,是指 TaskManager 具有的併發執行能力。

並行子任務的分配

Task Slot 是靜態的概念,是指 TaskManager 具有的併發執行能力,可以通過引數 taskmanager.numberOfTaskSlots 進行配置;而並行度 parallelism 是動態概念, 即 TaskManager 執行程式時實際使用的併發能力,可以通過引數 parallelism.default 進行配置。

也就是說,假設一共有 3 個 TaskManager,每一個 TaskManager 中的分配 3 個 TaskSlot,也就是每個 TaskManager 可以接收 3 個 task,一共 9 個 TaskSlot,如果我 們設定 parallelism.default=1,即執行程式預設的並行度為 1,9 個 TaskSlot 只用了 1 個,有 8 個空閒,因此,設定合適的並行度才能提高效率。

程式結構和資料流圖

程式與資料流(DataFlow)

所有的Flink程式都是由三部分組成的: Source 、Transformation 和 Sink。

Source 負責讀取資料來源,Transformation 利用各種運算元進行處理加工,Sink 負責輸出

在執行時,Flink上執行的程式會被對映成“邏輯資料流”(dataflows),它包含了這三部分

每一個dataflow以一個或多個sources開始以一個或多個sinks結束。dataflow 類似於任意的有向無環圖(DAG)

在大部分情況下,程式中的轉換運算(transformations)跟dataflow中的運算元 (operator)是一一對應的關係。

執行圖(ExecutionGraph)

Flink 中的執行圖可以分成四層:StreamGraph -> JobGraph -> ExecutionGraph -> 物理執行圖

StreamGraph:是根據使用者通過 Stream API 編寫的程式碼生成的最初的圖。用來表示程式的拓撲結構。

JobGraph:StreamGraph經過優化後生成了 JobGraph,提交給 JobManager 的資料結構。主要的優化為,將多個符合條件的節點 chain 在一起作為一個節點

ExecutionGraph:JobManager 根據 JobGraph 生成ExecutionGraph。

ExecutionGraph是JobGraph的並行化版本,是排程層最核心的資料結構。

物理執行圖:JobManager 根據 ExecutionGraph 對 Job 進行排程後,在各個TaskManager 上部署 Task 後形成的“圖”,並不是一個具體的資料結構。

資料傳輸形式

一個程式中,不同的運算元可能具有不同的並行度

運算元之間傳輸資料的形式可以是 one-to-one (forwarding) 的模式也可以是 redistributing 的模式,具體是哪一種形式,取決於運算元的種類

One-to-one:stream維護著分割槽以及元素的順序(比如source和map之間)。 這意味著map 運算元的子任務看到的元素的個數以及順序跟 source 運算元的子任務生產的元素的個數、順序相同。map、fliter、flatMap等運算元都是one-to-one 的對應關係。

Redistributing:stream的分割槽會發生改變。每一個運算元的子任務依據所選擇的 transformation傳送資料到不同的目標任務。例如,keyBy 基於 hashCode 重分割槽、而 broadcast 和 rebalance 會隨機重新分割槽,這些運算元都會引起 redistribute過程,而 redistribute 過程就類似於 Spark 中的 shuffle 過程。

任務鏈(Operator Chains)

Flink 採用了一種稱為任務鏈的優化技術,可以在特定條件下減少本地通訊的開銷。為了滿足任務鏈的要求,必須將兩個或多個運算元設為相同的並行度,並通過本地轉發(local forward)的方式進行連線

相同並行度的 one-to-one 操作,Flink 這樣相連的運算元連結在一起形 成一個 task,原來的運算元成為裡面的 subtask

並行度相同、並且是 one-to-one 操作,兩個條件缺一不可