A.而若Key 的數量比實例數量少,就會致使部分實例收不到數據,這些實例就得不到執行,這些實例的計算能力得不到充分發揮。
B.當Key個數多餘並行實例數時,因爲同一個 Key 對應的全部數據都能發送到同一個計算實例上,同一個Key中所對應的數據都能分配到同一個實例中,這樣Key內計算就免去了數據傳遞的序列化和網絡IO等開銷。網絡
前面咱們調用的全部方法,都不是在實際處理數據,而是在構通表達計算邏輯的DAG圖。只有當咱們將整個圖構建完成並顯式調用 Execute 方法後,框架纔會把計算圖提交到集羣中,接入數據並執行實際的邏輯。session
其中master負責管理整個集羣中的資源和做業;而TaskExecutor 則是 Slave,負責提供具體的資源並實際執行做業。架構
A.Dispatcher負責接收用戶提供的做業,而且負責爲這個新提交的做業拉起一個新的 JobManager 組件。
B.ResourceManager 負責資源的管理,在整個 Flink 集羣中只有一個 ResourceManager。
C.JobManager 負責管理做業的執行,在一個 Flink 集羣中可能有多個做業同時執行,每一個做業都有本身的 JobManager 組件。
以上三個組件都包含在 AppMaster 進程中。併發
它先將用戶編寫的代碼編譯爲一個 JobGraph,在這個過程,它還會進行一些檢查或優化等工做,如判斷哪些 Operator 能夠 Chain 到同一個 Task 中。而後,Client 將產生的 JobGraph 提交到集羣中執行。此時有兩種狀況,一種是相似於 Standalone 這種 Session 模式,AM 會預先啓動,此時 Client 直接與 Dispatcher 創建鏈接並提交做業便可。另外一種是 Per-Job 模式,AM 不會預先啓動,此時 Client 將首先向資源管理系統 (如Yarn、K8S)申請資源來啓動 AM,而後再向 AM 中的 Dispatcher 提交做業。框架
Dispatcher 會先啓動一個 JobManager 組件,而後 JobManager 會向 ResourceManager 申請資源來啓動做業中具體的任務。這時根據 Session 和 Per-Job 模式的區別, TaskExecutor 可能已經啓動或者還沒有啓動。如果前者,此時 ResourceManager 中已有記錄了 TaskExecutor 註冊的資源,能夠直接選取空閒資源進行分配。如果後者,ResourceManager 也須要先向外部資源管理系統申請資源來啓動 TaskExecutor,而後等待 TaskExecutor 註冊相應資源後再繼續選擇空閒資源進程分配。
目前 Flink 中 TaskExecutor 的資源是經過 Slot 來描述的,一個 Slot 通常能夠執行一個具體的 Task,但在一些狀況下也能夠執行多個相關聯的 Task。ResourceManager 選擇到空閒的 Slot 以後,就會通知相應的 TM 「將該 Slot 分配給 JobManager XX 」,而後 TaskExecutor 進行相應的記錄後,會向 JobManager 進行註冊。JobManager 收到 TaskExecutor 註冊上來的 Slot 後,就能夠實際提交 Task 了。TaskExecutor 收到 JobManager 提交的 Task 以後,會啓動一個新的線程來執行該 Task。Task 啓動後就會開始進行預先指定的計算,並經過數據 Shuffle 模塊互相交換數據。性能
7.1Per-job 模式下整個 Flink 集羣只執行單個做業,即每一個做業會獨享 Dispatcher 和 ResourceManager 組件。此外,Per-job 模式下 AppMaster 和 TaskExecutor 都是按需申請的。所以,Per-job 模式更適合運行執行時間較長的大做業,這些做業對穩定性要求較高,而且對申請資源的時間不敏感。【通常配合yarn、mesose、k8s等外部資源管理器】
7.2與之對應,在 Session 模式下,Flink 預先啓動 AppMaster 以及一組 TaskExecutor,而後在整個集羣的生命週期中會執行多個做業。能夠看出,Session 模式更適合規模小,執行時間短的做業。【通常在standalone模式下使用】優化