天天看點

深入淺出總結Flink運作時架構。

一、Flink運作時各個元件介紹

Flink 運作時架構主要包括四個不同的元件,它們會在運作流處理應用程式時協同工作:​

​作業管理器(JobManager)​

​​、​

​資料總管(ResourceManager)​

​​、​

​任務管理器(TaskManager)​

​​,以及​

​分發器(Dispatcher)​

​。因為 Flink 是用 Java 和 Scala 實作的,是以所有元件都會運作在Java 虛拟機上。接下來對各個元件的功能進行簡單介紹i。

作業管理器(JobManager)

作業管理器它會控制一個應用程式的主程序,每個應用程式都會被一個不同的JobManager 所控制執行。JobManager 會向資料總管(ResourceManager)請求執行任務必要的資源,也就是任務管理器(TaskManager)上的插槽(slot)。一旦它擷取到了足夠的資源,就會将執行圖分發到真正運作它們的TaskManager 上。而在運作過程中,JobManager 會負責所有需要中央協調的操作,比如說檢查點(checkpoints)的協調。

資料總管(ResourceManager)

主要負責管理任務管理器(TaskManager)的插槽(slot),TaskManger 插槽是 Flink 中定義的處理資源單元。Flink 為不同的環境和資源管理工具提供了不同資料總管,比如YARN、Mesos、K8s,以及 standalone 部署。當 JobManager 申請插槽資源時,ResourceManager會将有空閑插槽的 TaskManager 配置設定給 JobManager。如果 ResourceManager 沒有足夠的插槽來滿足 JobManager 的請求,它還可以向資源提供平台發起會話,以提供啟動 TaskManager程序的容器。另外,ResourceManager 還負責終止空閑的 TaskManager,釋放計算資源。

任務管理器(TaskManager)

Flink 中的工作程序。通常在 Flink 中會有多個 TaskManager 運作,每一個 TaskManager都包含了一定數量的插槽(slots)。插槽的數量限制了 TaskManager 能夠執行的任務數量。啟動之後,TaskManager 會向資料總管注冊它的插槽;收到資料總管的指令後,TaskManager 就會将一個或者多個插槽提供給 JobManager 調用。JobManager 就可以向插槽配置設定任務(tasks)來執行了。在執行過程中,一個 TaskManager 可以跟其它運作同一應用程

序的 TaskManager 交換資料。

分發器(Dispatcher)

可以跨作業運作,它為應用送出提供了 REST 接口。當一個應用被送出執行時,分發器就會啟動并将應用移交給一個 JobManager。由于是 REST 接口,是以 Dispatcher 可以作為叢集的一個 HTTP 接入點,這樣就能夠不受防火牆阻擋。Dispatcher 也會啟動一個 Web UI,用來友善地展示和監控作業執行的資訊。Dispatcher 在架構中可能并不是必需的,這取決于應用送出運作的方式。

二、Flink任務送出的流程

上面介紹完了flink運作時架構的各個元件對應的功能,接下來我們看一下他們互相之間都是怎麼協作運轉的。

一般的互動協作圖:

深入淺出總結Flink運作時架構。

送出一個flink程式到分發器,分發器(Dispatcher)将送出的應用移交給任務管理器(JobManager),然後向資料總管(ResourceManager)請求執行任務必要的資源,接着資料總管會将有空閑插槽的 TaskManager 配置設定給 JobManager,然後JobManager會将要在插槽中執行的任務送出給TaskManager 。

具體到Yarn上的互動圖

深入淺出總結Flink運作時架構。
  • Client 為送出 Job 的用戶端,可以是運作在任何機器上(與 JobManager 環境連通即可)。送出 Job 後,Client 可以結束程序(Streaming 的任務),也可以不結束并等待結果傳回。
  • JobManager 主 要 負 責 調 度 Job 并 協 調 Task 做 checkpoint, 職 責 上 很 像Storm 的 Nimbus。從 Client 處接收到 Job 和 JAR 包等資源後,會生成優化後的執行計劃,并以 Task 的單元排程到各個 TaskManager 去執行。
  • TaskManager 在啟動的時候就設定好了槽位數(Slot),每個 slot 能啟動一個Task,Task 為線程。從 JobManager 處接收需要部署的 Task,部署啟動後,與自己的上遊建立 Netty 連接配接,接收資料并處理

三、Flink任務排程原理

深入淺出總結Flink運作時架構。

Flink 集 群 啟 動 後 , 首 先 會 啟 動 一 個 JobManger 和一個或多個的TaskManager。由 Client 送出任務給 JobManager,JobManager 再排程任務到各個TaskManager 去執行,然後 TaskManager 将心跳和統計資訊彙報給 JobManager。TaskManager 之間以流的形式進行資料的傳輸。上述三者均為獨立的 JVM 程序。

TaskManger 與 Slots

  • 一個 Worker(TaskManager)就是一個 JVM 程序,内部擁有一個或多個 Task Slot 進一步細分程序的 CPU 資源。
深入淺出總結Flink運作時架構。
  • Slot 是指 TaskManager 最大能并發執行的能力->taskmanager.numberOfTaskSlots->ys
  • parallelism 是指 TaskManager 實際使用的并發能力->parallelism.default->p
  • 同一Slot 中的線程共享相同的 JVM。 同一 JVM 中的任務共享 TCP 連接配接和心跳消息。TaskManager 的一個 Slot 代表一個可用線程,該線程具有固定的記憶體,注意 Slot 隻對記憶體隔離,沒有對 CPU 隔離
深入淺出總結Flink運作時架構。
假設一共有 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)是一一對應的關系,但有時候,一個 transformation 可能對應多個 operator。

并行度(Parallelism)

Flink 程式的執行具有并行、分布式的特性。一個特定算子的子任務(subtask)的個數被稱之為其并行度(parallelism)。一個流程式的并行度,可以認為就是其所有算子中最大的并行度。一個程式中,不同的算子可能具有不同的并行度。

深入淺出總結Flink運作時架構。

Stream 在算子之間傳輸資料的形式有兩種模式。

  • One-to-one:stream(比如在 source 和 map operator 之間)維護着分區以及元素的順序。那意味着 map 算子的子任務看到的元素的個數以及順序跟 source 算子的子任務生産的元素的個數、順序相同,map、fliter、flatMap 等算子都是 one-to-one 的對應關系。
  • Redistributing:stream(map()跟 keyBy/window 之間或者 keyBy/window 跟 sink之間)的分區會發生改變。每一個算子的子任務依據所選擇的 transformation 發送資料到不同的目标任務。例如,keyBy() 基于 hashCode 重分區、broadcast 和 rebalance會随機重新分區,這些算子都會引起 redistribute 過程

繼續閱讀