天天看點

快速入門Flink (3) —— Flink的運作架構

寫在前面: 部落客是一名大資料的初學者,昵稱來源于《愛麗絲夢遊仙境》中的Alice和自己的昵稱。作為一名網際網路小白,

寫部落格一方面是為了記錄自己的學習曆程,一方面是希望能夠幫助到很多和自己一樣處于起步階段的萌新

。由于水準有限,部落格中難免會有一些錯誤,有纰漏之處懇請各位大佬不吝賜教!

盡管目前水準可能不及各位大佬,但我還是希望自己能夠做得更好,因為

一天的生活就是一生的縮影

。我希望

在最美的年華,做最好的自己

        通過快速入門Flink的前幾篇部落格,部落客已經為大家介紹了關于Flink的簡介與架構體系以及常用幾種不同模式的叢集搭建過程。。本篇部落格,部落客為大家帶來的是Flink的運作架構的介紹。

        碼字不易,先贊後看!

文章目錄

    • 1、Flink的運作架構
      • 1.1 任務送出流程
      • 1.2 Worker 與 Slots
      • 1.3 程式與資料流
      • 1.4 并行資料流
      • 1.5 task 與 operator chains
    • 小結

快速入門Flink (3) —— Flink的運作架構

        Flink 任務送出後,Client 向 HDFS 上傳 Flink 的 Jar 包和配置,之後向 Yarn ResourceManager 提 交 任 務 ,ResourceManager 分 配 Container 資 源 并 通 知 對 應 的 NodeManager 啟 動 ApplicationMaster,ApplicationMaster 啟動後加載 Flink 的 Jar 包 和 配 置 構 建 環 境 , 然 後 啟 動 JobManager , 之 後 ApplicationMaster 向 ResourceManager 申 請 資 源 啟 動 TaskManager ,ResourceManager 分 配 Container 資 源 後 , 由 ApplicationMaster 通 知 資 源 所 在 節 點 的 NodeManager 啟動 TaskManager,NodeManager 加載 Flink 的 Jar 包和配置建構環境并啟動 TaskManager, TaskManager 啟動後向 JobManager 發送心跳包,并等待 JobManager 向其配置設定任務。

        每一個 worker(TaskManager)是一個 JVM 程序,它可能會在獨立的線程上執行一個或 多個 subtask。為了控制一個 worker 能接收多少個 task,worker 通過 task slot 來進 行控制(一個 worker 至少有一個 task slot)。

        每個 task slot 表示 TaskManager 擁有資源的一個固定大小的子集。假如一個 TaskManager 有三個 slot,那麼它會将其管理的記憶體分成三份給各個 slot。資源 slot 化 意味着一個 subtask 将不需要跟來自其他 job 的 subtask 競争被管理的記憶體,取而代之 的是它将擁有一定數量的記憶體 儲備。需要注意的是,這裡不會涉及到 CPU 的隔離,slot 目前僅僅用來隔離 task 的受管理的記憶體。

        通過調整 task slot 的數量,允許使用者定義 subtask 之間如何互相隔離。如果一個 TaskManager 一個 slot,那将意味着每個 task group 運作在獨立的 JVM 中(該 JVM 可能是通過一個特定的容器啟動的),而一個 TaskManager 多個 slot 意味着更多的 subtask 可以共享同一 個 JVM。而在同一個 JVM 程序中的 task 将共享 TCP 連接配接(基于多路複用) 和心跳消息。它們也可能共享資料集和資料結構,是以這減少了每個 task 的負載。

快速入門Flink (3) —— Flink的運作架構

        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 個空閑,是以,設定合适的并行度才能提高效率。

        Flink 程式的基礎構模組化塊是流(streams) 與 轉換(transformations)(需要注意 的是,Flink 的 DataSet API 所使用的 DataSets 其内部也是 stream)。一個 stream 可 以看成一個中間結果,而一個 transformations 是以一個或多個 stream 作為輸入的某種 operation,該 operation 利用這些 stream 進行計算進而産生一個或多個 result stream。

        在運作時,Flink 上運作的程式會被映射成 streaming dataflows,它包含了 streams 和 transformations operators。每一個 dataflow 以一個或多個 sources 開始以一個或 多個 sinks 結束。dataflow 類似于任意的有向無環圖(DAG),當然特定形式的環可以通過 iteration 建構。 在大部分情況下,程式中的 transformations 跟 dataflow 中的 operator 是一一對應的關系,但有時候,一個 transformation 可能對應多個 operator。

快速入門Flink (3) —— Flink的運作架構

        Flink 程式的執行具有并行、分布式的特性。在執行過程中,一個 stream 包含一個或多個 stream partition ,而每一個 operator 包含一個或多個 operator subtask,這些 operator subtasks 在不同的線程、不同的實體機或不同的容器中彼此互不依賴得執行。

        一個特定 operator 的 subtask 的個數被稱之為其 parallelism(并行度)。一個 stream 的并行度總是等同于其 producing operator 的并行度。一個程式中,不同的 operator 可能具有不同的并行度。

快速入門Flink (3) —— Flink的運作架構

        Stream 在 operator 之間傳輸資料的形式可以是 one-to-one(forwarding)的模式也 可以是 redistributing 的模式,具體是哪一種形式,取決于 operator 的種類。

        One-to-one:stream(比如在 source 和 map operator 之間)維護着分區以及元素的順序。那意味着 map operator 的 subtask 看到的元素的個數以及順序跟 source operator 的 subtask 生産的元素的個數、順序相同,map、fliter、flatMap 等算子都是 one-to-one 的對應關系。

        Redistributing:stream(map()跟 keyBy/window 之間或者 keyBy/window 跟 sink 之 間)的分 區會發生改變。每一個 operator subtask 依據所選擇的 transformation 發送數 據到不同的目标 subtask。例如,keyBy() 基于 hashCode 重分區、broadcast 和 rebalance 會随機重新分區,這些算子都會引起 redistribute 過程,而 redistribute 過程就類似 于 Spark 中的 shuffle 過程。

        出于分布式執行的目的,Flink 将 operator 的 subtask 連結在一起形成 task,每個 task 在 一個線程中執行。将 operators 連結成 task 是非常有效的優化:它能減少線程之 間的切換和基于緩存區的資料交換,在減少時延的同時提升吞吐量。連結的行為可以在程式設計 API 中進行指定。

        下面這幅圖,展示了 5 個 subtask 以 5 個并行的線程來執行:

快速入門Flink (3) —— Flink的運作架構

        聯系我們之前學習的SparkStreaming,來看看一些概念名詞上的差異。

快速入門Flink (3) —— Flink的運作架構

        本篇部落格部落客為大家詳細介紹了Flink的運作架構。下一篇部落格,我們将正式上手Flink的實戰代碼,敬請期待|ू・ω・` )

        如果以上過程中出現了任何的纰漏錯誤,煩請大佬們指正????

繼續閱讀