Flink網絡棧是Flink中的核心組件,是flink-runtime模塊的一部分。它連接了所有TaskManager中獨立的工作單元(subtask)。這是數據交換的核心部分,任務的吞吐量和延遲都與它息息相關,可以說Flink的網絡棧決定了Flink框架本身性能的好壞。
不同于TaskManager、JobManager之間通信所使用的Akka RPC框架,Flink網絡棧采用了更底層的網絡API,使用的是Netty框架。
它抽象了以下三個概念的不同設置。
(資料圖片僅供參考)
工作單元的輸出類型和調度類型是緊密交織在一起的,兩者的特定組合才有效。Pipelined result partition是流式的輸出,流式輸出需要將數據發送到一個正在工作的工作單元,因此目標任務就需要在上游結果下發之前或者在任務啟動之初完成部署。批作業產出有限的結果,而流式作業產出無限的結果。
為了理解真實的數據流轉,我們假想一個有4個并發的任務,部署在兩個分別有2個Slot的TaskManager上。在Flink中,不同的任務可能會共享同一個Slot, 通過Slot 共享組機制,一個TaskManager可以提供多個Slot來運行一個任務的多個工作單元。
TaskManager 1 運行工作單元A.1、A.2、B.1 和 B.2, 而TaskManager 2 運行工作單元A.3、A.4、B.3和B.4。假設A和B之間的shuffle方式是keyBy(), 這樣在每一個TaskManager上都有2×4個邏輯連接,有些走本地傳輸,有些是通過網絡傳輸,如圖1所示。
▲圖1 工作單元部署
不同任務之間的每個(遠程)網絡連接都將在Flink網絡棧中獲得自己的TCP通道,如果同一個任務的不同工作單元被調度到同一個TaskManager上,那么它們將復用TCP連接用于連接遠程TM(多路復用)。在我們的例子中,A.1 → B.3、A.1 → B.4 以及A.2 → B.3、A.2 → B.4將會復用一個TCP連接,如圖2所示。
▲圖2 數據交換
每個工作單元的輸出被稱作ResultPartition,每個ResultPartition又根據下游輸出結果的不同分區被細分為ResultSubPartition,與下游的inputChannel一一對應。在這個階段,Flink已經不再單獨處理每條記錄了,而是將一組序列化完的數據打包并復制到NetworkBuffer中,然后經由Netty傳輸到下游算子。
本文摘編于《Flink技術內幕:架構設計與實現原理》,經出版方授權發布。(書號:9787111696292)轉載請保留文章來源。?
標簽: Flink