Flink架構(二)- Flink中的數據傳輸


2. Flink中的數據傳輸

在一個運行的application中,它的tasks在持續交換數據。TaskManager負責做數據傳輸。TaskManager的網絡組件首先從緩沖buffer中收集records,然后再發送。也就是說,records並不是一個接一個的發送,而是先放入緩沖,然后再以batch的形式發送。這個技術可以高效使用網絡資源,並達到高吞吐。類似於網絡或磁盤 I/O 協議中使用的緩沖技術。

這里需要注意的是:傳輸緩沖buffer中的記錄,隱含表示的是,Flink的處理模型是基於微批處理的。

每個TaskManager有一組網絡緩沖池(默認每個buffer32KB),用於發送與接受數據。如發送端和接收端位於不同的TaskManager進程中,則它們需要通過操作系統的網絡棧進行交流。流應用需要以管道的模式進行數據交換,也就是說,每對TaskManager會維持一個永久的TCP連接用於做數據交換。在shuffle連接模式下(多個sender與多個receiver),每個sender task需要向每個receiver task,此時TaskManager需要為每個receiver task都分配一個緩沖區。下圖展示了此架構:

 

在上圖中,有四個sender 任務,對於每個sender,都需要有至少四個network buffer用於向每個receiver發送數據。每個receiver都需要有至少四個buffer用於接收數據。TaskManager之間的buffer以多路復用的方式使用同一網絡連接。為了提供平滑的數據管道型的數據交換,一個TaskManager必須能提供足夠的緩沖,以服務所有並行的出入連接。對於shufflebroadcast 連接,每個發送任務和每個接受任務之間都需要一個bufferFlink的默認網絡緩沖配置足夠適用與小型與中型的集群任務。對於大型的集群任務,需要對此配置進行調優。

senderreceiver任務都運行在同一個TaskManager進程,則sender任務會將發送的條目做序列化,並存入一個字節緩沖。然后將緩沖放入一個隊列,直到隊列被填滿。Receiver任務從隊列中獲取緩沖,並反序列化輸入的條目。所以,在同一個TaskManager內,任務之間的數據傳輸並不經過網絡交互。

Flink采用了不同的技術用於減少tasks之間的溝通成本。在接下來的部分中,我們會討論基於積分的(credit-based )流控制與任務鏈(task chaining)。

 

基於積分的(Credit-Based )流控制

通過網絡發送單獨的條目是一個並不高效的方式,並且會造成大量負載。使用緩沖技術可以更好的使用網絡連接的帶寬。在流處理場景中,緩沖的一個缺點是:它增加了延時,因為records需要先放入緩沖,而不是被立即傳輸。

Flink實現了一個credit-based 流控制機制,工作方式為:一個接收任務會授權給一個發送任務一些積分(credit),用於控制預留的緩沖區個數。當一個sender接收到了積分通知,它向會receiver發送 buffers(最多不超過被授權的數量)以及它的backlog大小(已經充滿了並等待被發送的buffer數量)。Receiver使用預留的buffer處理接收到的數據,並使用senderbacklog大小作為下一次授權的積分數,提供給所有與它連接的senders

Credit-based 流控制減少了延時,因為senders可以在receiver有足夠的資源接受數據時,盡快向它發送數據。它在Flink中是一個重要的部分,助力Flink達到高吞吐與低延時。

 

任務鏈(task chaining

Flink另一個優化技術稱為任務鏈,用於(在某些情況下)減少本地通信的過載。為了滿足任務鏈的條件,至少兩個以上的operator必須配置為同一並行度,並且使用本地向前的(local forwad)方式連接。下圖的operator管道即滿足這些條件。它包含3operators,全部被配置為並行度為2,並且以local-forward的方式連接:

 

 

下圖描述了管道是如何以任務鏈的方式執行的。Operators的函數被融合成單個任務,並由一個單獨的線程執行。一個function產生的records,通過使用一個簡單的方法調用,被遞交給下一個function。所以,這里在方法之間的records傳遞中,基本沒有序列化以及通信消耗。

 

 

 

任務鏈可以極大減少本地task之間的通信成本,但是有時候在執行一個管道時,不使用任務鏈也是合理的。例如,將一個包含多個鏈式任務的長管道斷開,或是將一個鏈分成兩個任務,並將較為消耗資源的function調度到另一個slot上。這些都是合理的。下圖描繪了同樣一個執行的管道,但未使用任務鏈。所有function由一個單獨的task,在它自身的線程中運行。

 

 

任務鏈默認是開啟的。在“控制任務鏈”一節,我們會介紹如何為某個任務關閉任務鏈化,以及如何控制單個operator的鏈行為。

 

References:

Vasiliki Kalavri, Fabian Hueske. Stream Processing With Apache Flink. 2019


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM