flink运行原理_浅谈Flink分布式运行时和数据流图的并行化
本文將以WordCount的案例為主線,主要介紹Flink的設(shè)計和運行原理。關(guān)于Flink WordCount程序可以參考我之前的文章:讀取Kafka實時數(shù)據(jù)流,實現(xiàn)Flink WordCount。閱讀完本文后,讀者可以對Flink的分布式運行時有一個全面的認(rèn)識。
原創(chuàng)不易,轉(zhuǎn)載請注明出處。對大數(shù)據(jù)和AI感興趣的朋友可以加我的微信 aistevelu,相互交流學(xué)習(xí)。
1 Flink數(shù)據(jù)流圖簡介
1.1 Flink作業(yè)的邏輯視圖
在大數(shù)據(jù)領(lǐng)域,詞頻統(tǒng)計(WordCount)程序就像是一個編程語言的HelloWorld程序,它展示了一個大數(shù)據(jù)引擎的基本規(guī)范。麻雀雖小,五臟俱全,從這個樣例中,我們可以一窺Flink設(shè)計和運行原理。
圖 1 Flink樣例程序示意圖如圖 1所示,程序分為三大部分,第一部分讀取數(shù)據(jù)源(Source),第二部分對數(shù)據(jù)做轉(zhuǎn)換操作(Transformation),最后將轉(zhuǎn)換結(jié)果輸出到一個目的地(Sink)。 代碼中的方法被稱為算子(Operator),是Flink提供給程序員的接口,程序員需要通過這些算子對數(shù)據(jù)進(jìn)行操作。Source算子讀取數(shù)據(jù)源中的數(shù)據(jù),數(shù)據(jù)源可以是數(shù)據(jù)流、也可以存儲在文件系統(tǒng)中的文件。Transformation算子對數(shù)據(jù)進(jìn)行必要的計算處理。Sink算子將處理結(jié)果輸出,數(shù)據(jù)一般被輸出到數(shù)據(jù)庫、文件系統(tǒng)或下一個數(shù)據(jù)流程序。
我們可以把算子理解為1 + 2 運算中的加號,加號(+)是這個算子的一個符號表示,它表示對數(shù)字1和數(shù)字2做加法運算。同樣,在Flink或Spark這樣的大數(shù)據(jù)引擎中,算子對數(shù)據(jù)進(jìn)行某種操作,程序員可以根據(jù)自己的需求調(diào)用合適的算子,完成所需計算任務(wù)。常用的算子有map、flatMap、keyBy、timeWindow等,它們分別對數(shù)據(jù)流執(zhí)行不同類型的操作。
我們先對這個樣例程序中各個算子做一個簡單的介紹,關(guān)于這些算子的具體使用方式將在后續(xù)文章中詳細(xì)說明。
- flatMap
flatMap對輸入進(jìn)行處理,生成零到多個輸出。這里是一個簡單的分詞過程,對一行字符串按照空格切分,生成一個(word, 1)的二元組。
- keyBy
keyBy根據(jù)某個Key對數(shù)據(jù)重新分組。本例中是將flatMap生成的二元組(word, 1)中第一項作為Key,相同的單詞會被分到同一組。
- timeWindow
timeWindow是時間窗口函數(shù),用來界定對多長時間之內(nèi)的數(shù)據(jù)做統(tǒng)計。
- sum
sum為求和函數(shù)。sum(1)表示對二元組中第二個元素求和,因為經(jīng)過前面的keyBy,所有相同的單詞都被分到了一起,因此,在這個分組內(nèi),將單詞出現(xiàn)次數(shù)做加和,就得到出現(xiàn)的總次數(shù)。
圖 2 WordCont程序的邏輯視圖
在程序?qū)嶋H運行前,Flink會將用戶編寫的代碼做一個簡單處理,生成一個如圖2所示的邏輯視圖。圖 2展示了WordCount程序中,數(shù)據(jù)從不同算子間流動的情況。圖中,圓圈代表算子,圓圈間的箭頭代表數(shù)據(jù)流,數(shù)據(jù)流在Flink程序中經(jīng)過不同算子的計算,最終生成為目標(biāo)數(shù)據(jù)。其中,keyBy、timeWindow和sum共同組成了一個時間窗口上的聚合操作,被歸結(jié)為一個算子。我們可以在Flink的Web UI中,點擊一個作業(yè),查看這個作業(yè)的邏輯視圖。
對于詞頻統(tǒng)計這個案例,邏輯上來講無非是對數(shù)據(jù)流中的單詞做提取,然后使用一個Key-Value結(jié)構(gòu)對單詞做詞頻計數(shù),最后輸出結(jié)果即可,這樣的邏輯本可以用幾行代碼完成,改成使用算子形式,反而讓新人看著一頭霧水,為什么一定要用算子的形式來寫程序呢?實際上,算子進(jìn)化成當(dāng)前這個形態(tài),就像人類從石塊計數(shù),到手指計數(shù),到算盤計數(shù),再到計算機計數(shù)這樣的進(jìn)化過程一樣,盡管更低級的方式可以完成一定的計算任務(wù),但是隨著計算規(guī)模的增長,古老的計數(shù)方式存在著低效的弊端,無法完成更高級別和更大規(guī)模的計算需求。試想,如果我們不使用大數(shù)據(jù)引擎提供的算子,而是自己實現(xiàn)一套上述的計算邏輯,盡管我們可以快速完成當(dāng)前的詞頻統(tǒng)計的任務(wù),但是當(dāng)面臨一個新計算任務(wù)時,我們需要重新編寫程序,完成一整套計算任務(wù)。我們自己編寫代碼的橫向擴展性可能很低,當(dāng)輸入數(shù)據(jù)暴增時,我們需要做很大改動,以部署在更多機器上。
大數(shù)據(jù)引擎的算子對計算做了一些抽象,對于新人來說有一定學(xué)習(xí)成本,而一旦掌握這門技術(shù),人們所能處理的數(shù)據(jù)規(guī)模將成倍增加。大數(shù)據(jù)引擎的算子出現(xiàn),正是針對數(shù)據(jù)分布在多個節(jié)點的大數(shù)據(jù)場景下,需要一種統(tǒng)一的計算描述語言來對數(shù)據(jù)做計算而進(jìn)化出的新計算形態(tài)。基于Flink的算子,我們可以定義一個數(shù)據(jù)流的邏輯視圖,以此完成對大數(shù)據(jù)的計算。剩下那些數(shù)據(jù)交換、橫向擴展、故障恢復(fù)等問題全交由大數(shù)據(jù)引擎來解決。
1.2 從邏輯視圖到物理執(zhí)行
在絕大多數(shù)的大數(shù)據(jù)處理場景下,一臺機器節(jié)點無法處理所有數(shù)據(jù),數(shù)據(jù)被切分到多臺節(jié)點上。在大數(shù)據(jù)領(lǐng)域,當(dāng)數(shù)據(jù)量大到超過單臺機器處理能力時,需要將一份數(shù)據(jù)切分到多個分區(qū)(Partition)上,每個分區(qū)分布在一臺虛擬機或物理機上。
前一小節(jié)已經(jīng)提到,大數(shù)據(jù)引擎的算子提供了編程接口,我們可以使用算子構(gòu)建數(shù)據(jù)流的邏輯視圖。考慮到數(shù)據(jù)分布在多個節(jié)點的情況,邏輯視圖只是一種抽象,需要將邏輯視圖轉(zhuǎn)化為物理執(zhí)行圖,才能在分布式環(huán)境下執(zhí)行。
圖 3 樣例程序物理執(zhí)行示意圖
圖 3為WordCount程序的物理執(zhí)行圖,這里數(shù)據(jù)流分布在2個分區(qū)上。箭頭部分表示數(shù)據(jù)流分區(qū),圓圈部分表示算子在分區(qū)上的算子子任務(wù)(Operator Subtask)。從邏輯視圖變?yōu)槲锢韴?zhí)行圖后,FlatMap算子在每個分區(qū)都有一個算子子任務(wù),以處理該分區(qū)上的數(shù)據(jù):FlatMap[1/2]算子子任務(wù)處理第一個數(shù)據(jù)流分區(qū)上的數(shù)據(jù),以此類推。
算子子任務(wù)又被稱為算子實例,一個算子在并行執(zhí)行時,會有多個算子實例。即使輸入數(shù)據(jù)增多,我們也可以通過部署更多的算子實例來進(jìn)行橫向擴展。從圖 3中可以看到,除去Sink外的算子都被分成了2個算子實例,他們的并行度(Parallelism)為2,Sink算子的并行度為1。并行度是可以被設(shè)置的,當(dāng)設(shè)置某個算子的并行度為2時,也就意味著有這個算子有2個算子子任務(wù)(或者說2個算子實例)并行執(zhí)行。實際應(yīng)用中一般根據(jù)輸入數(shù)據(jù)量的大小,計算資源的多少等多方面的因素來設(shè)置并行度。
注意,在本例中,為了演示,我們把所有算子的并行度設(shè)置為了2:env.setParallelism(2);,把最后輸出的并行度設(shè)置成了1:wordCount.print().setParallelism(1);。如果不單獨設(shè)置print的并行度的話,它的并行度也是2。
算子子任務(wù)是Flink物理執(zhí)行的基本單元,算子子任務(wù)之間是相互獨立的,某個算子子任務(wù)有自己的線程,不同算子子任務(wù)可能分布在不同的節(jié)點上。后文在Flink的資源分配部分我們還會重點介紹算子子任務(wù)。
1.3 數(shù)據(jù)交換策略
圖 3中出現(xiàn)了數(shù)據(jù)流動的現(xiàn)象,即數(shù)據(jù)在不同的算子子任務(wù)上進(jìn)行著數(shù)據(jù)交換。無論是Hadoop、Spark還是Flink,都都會涉及到數(shù)據(jù)交換策略。常見的據(jù)交換策略有4種,如圖 4所示。
圖 4 Flink數(shù)據(jù)交換策略
2 Flink架構(gòu)與核心組件
為了實現(xiàn)支持分布式運行,Flink跟其他大數(shù)據(jù)引擎一樣,采用了主從(Master-Worker)架構(gòu),運行時主要包括兩個組件:
? Master是一個Flink作業(yè)的主進(jìn)程。它起到了協(xié)調(diào)管理的作用。
? TaskManager,又被稱為Worker或Slave,是執(zhí)行計算任務(wù)的進(jìn)程。它擁有CPU、內(nèi)存等計算資源。Flink作業(yè)需要將計算任務(wù)分發(fā)到多個TaskManager上并行執(zhí)行。
下面將從作業(yè)執(zhí)行層面來分析Flink各個模塊如何工作。
2.1 Flink作業(yè)執(zhí)行過程
Flink為適應(yīng)不同的基礎(chǔ)環(huán)境(獨立集群、YARN、Kubernetes),在不斷的迭代開發(fā)過程中已經(jīng)逐漸形成了一個作業(yè)執(zhí)行流程。不同的基礎(chǔ)環(huán)境對計算資源的管理方式略有不同,不過都大同小異,這里以獨立集群(Standalone)為例,分析作業(yè)的分布式執(zhí)行流程。Standalone模式指Flink獨占該集群,集群上無其他任務(wù),如Spark、MapReduce等。
圖 5 Flink作業(yè)提交流程
在一個作業(yè)提交前,Master和TaskManager等進(jìn)程需要先被啟動。我們可以在Flink主目錄中執(zhí)行腳本來啟動這些進(jìn)程:bin/start-cluster.sh。Master和TaskManager被啟動后,TaskManager需要將自己注冊給Master中的ResourceManager。這個初始化和資源注冊過程發(fā)生在單個作業(yè)提交前,我們稱之為第0步。
接下來我們逐步分析一個Flink作業(yè)如何被提交:
TaskManager在執(zhí)行計算任務(wù)過程中可能會與其他TaskManager交換數(shù)據(jù),會使用圖 4提到的一些數(shù)據(jù)交換策略。同時,TaskManager也會將一些任務(wù)狀態(tài)信息會反饋給JobManager,這些信息包括任務(wù)啟動、運行或終止的狀態(tài),快照的元數(shù)據(jù)等。
我們再對涉及到的各個組件進(jìn)行更為詳細(xì)的介紹。
Client
用戶一般使用客戶端(Client)提交作業(yè),比如Flink主目錄下的bin目錄中提供的命令行工具。Client會對用戶提交的Flink程序進(jìn)行預(yù)處理,并把作業(yè)提交到Flink集群上。Client提交作業(yè)時需要配置一些必要的參數(shù),比如使用Standalone還是YARN集群等。整個作業(yè)被打成了Jar包,DataStream API被轉(zhuǎn)換成了JobGraph,JobGraph是一種類似圖2的邏輯視圖。
Dispatcher
Dispatcher可以接收多個作業(yè),每接收一個作業(yè),Dispatcher都會為這個作業(yè)分配一個JobManager。Dispatcher對外提供一個REST式的接口,以HTTP的形式來對外提供服務(wù)。
JobManager
JobManager是單個Flink作業(yè)的協(xié)調(diào)者,一個作業(yè)會有一個JobManager來負(fù)責(zé)。JobManager會將Client提交的JobGraph轉(zhuǎn)化為ExceutionGraph,ExecutionGraph是類似圖3所示的可并行的物理執(zhí)行圖。JobManager會向ResourceManager申請必要的資源,當(dāng)獲取足夠的資源后,JobManager將ExecutionGraph以及具體的計算任務(wù)分發(fā)部署到多個TaskManager上。同時,JobManager還負(fù)責(zé)管理多個TaskManager,這包括:收集作業(yè)的狀態(tài)信息,生成檢查點,必要時進(jìn)行故障恢復(fù)等問題。
ResourceManager
如前文所說,Flink現(xiàn)在可以部署在Standalone、YARN或Kubernetes等環(huán)境上,不同環(huán)境中對計算資源的管理模式略有不同,Flink使用一個名為ResourceManager的模塊來統(tǒng)一處理資源分配上的問題。在Flink中,計算資源的基本單位是TaskManager上的任務(wù)槽位(Task Slot,簡稱槽位Slot)。ResourceManager的職責(zé)主要是從YARN等資源提供方獲取計算資源,當(dāng)JobManager有計算需求時,將空閑的Slot分配給JobManager。當(dāng)計算任務(wù)結(jié)束時,ResourceManager還會重新收回這些Slot。
TaskManager
TaskManager是實際負(fù)責(zé)執(zhí)行計算的節(jié)點。一般地,一個Flink作業(yè)是分布在多個TaskManager上執(zhí)行的,單個TaskManager上提供一定量的Slot。一個TaskManager啟動后,相關(guān)Slot信息會被注冊到ResourceManager中。當(dāng)某個Flink作業(yè)提交后,TaskManager會將空閑的Slot信息提供給JobManager。JobManager獲取到空閑Slot信息后會將具體的計算任務(wù)部署到該Slot之上,任務(wù)開始在這些Slot上執(zhí)行。在執(zhí)行過程,由于要進(jìn)行數(shù)據(jù)交換,TaskManager還要和其他TaskManager進(jìn)行必要的數(shù)據(jù)通信。
總之,TaskManager負(fù)責(zé)具體計算任務(wù)的執(zhí)行,啟動時它會將資源向ResourceManager注冊。
2.2 再談邏輯視圖到物理執(zhí)行圖
了解了Flink的分布式架構(gòu)和核心組件,這里我們從更細(xì)粒度上來介紹從邏輯視圖轉(zhuǎn)化為物理執(zhí)行圖過程,該過程可以分成四層:StreamGraph -> JobGraph -> ExecutionGraph -> 物理執(zhí)行圖。
圖 6 WordCount程序數(shù)據(jù)流圖轉(zhuǎn)化過程
- StreamGraph:是根據(jù)用戶編寫的代碼生成的最初的圖,用來表示一個Flink作業(yè)的拓?fù)浣Y(jié)構(gòu)。在StreamGraph中,節(jié)點StreamNode就是算子。
- JobGraph:JobGraph是提交給 JobManager 的數(shù)據(jù)結(jié)構(gòu)。StreamGraph經(jīng)過優(yōu)化后生成了JobGraph,主要的優(yōu)化為,將多個符合條件的節(jié)點鏈接在一起作為一個JobVertex節(jié)點,這樣可以減少數(shù)據(jù)交換所需要的傳輸開銷。這個鏈接的過程叫做算子鏈(Operator Chain),會在下一小節(jié)繼續(xù)介紹。JobVertex經(jīng)過算子鏈后,會包含一到多個算子,它輸出是IntermediateDataSet,是經(jīng)過算子處理產(chǎn)生的數(shù)據(jù)集。
- ExecutionGraph:JobManager將 JobGraph轉(zhuǎn)化為ExecutionGraph。ExecutionGraph是JobGraph的并行化版本:假如某個JobVertex的并行度是2,那么它將被劃分為2個ExecutionVertex,ExecutionVertex表示一個算子子任務(wù),它監(jiān)控著單個子任務(wù)的執(zhí)行情況。每個ExecutionVertex會輸出一個IntermediateResultPartition,這是單個子任務(wù)的輸出,再經(jīng)過ExecutionEdge輸出到下游節(jié)點。ExecutionJobVertex是這些并行子任務(wù)的合集,它監(jiān)控著整個算子的運行情況。ExecutionGraph是調(diào)度層非常核心的數(shù)據(jù)結(jié)構(gòu)。
- 物理執(zhí)行圖:JobManager根據(jù)ExecutionGraph對作業(yè)進(jìn)行調(diào)度后,在各個TaskManager上部署具體的任務(wù),物理執(zhí)行圖并不是一個具體的數(shù)據(jù)結(jié)構(gòu)。
可以看到,Flink在數(shù)據(jù)流圖上可謂煞費苦心,僅各類圖就有四種之多。對于新人來說,可以不用太關(guān)心這些非常細(xì)節(jié)的底層實現(xiàn),只需要了解以下幾個核心概念:
- Flink采用主從架構(gòu),Master起著管理協(xié)調(diào)作用,TaskManager負(fù)責(zé)物理執(zhí)行,在執(zhí)行過程中會發(fā)生一些數(shù)據(jù)交換、生命周期管理等事情。
- 用戶調(diào)用Flink API,構(gòu)造邏輯視圖,Flink會對邏輯視圖優(yōu)化,并轉(zhuǎn)化為并行化的物理執(zhí)行圖,最后被執(zhí)行的是物理執(zhí)行圖。
2.3 任務(wù)、算子子任務(wù)與算子鏈
在構(gòu)造物理執(zhí)行圖的過程中,Flink會將一些算子子任務(wù)鏈接在一起,組成算子鏈。鏈接后以任務(wù)(Task)的形式被TaskManager調(diào)度執(zhí)行。使用算子鏈?zhǔn)且粋€非常有效的優(yōu)化,它可以有效降低算子子任務(wù)之間的傳輸開銷。鏈接之后形成的Task是TaskManager中的一個線程。
圖 7 任務(wù)、子任務(wù)與算子鏈
例如,數(shù)據(jù)從Source前向傳播到FlatMap,這中間沒有發(fā)生跨分區(qū)的數(shù)據(jù)交換,因此,我們完全可以將Source、FlatMap這兩個子任務(wù)組合在一起,形成一個Task。數(shù)據(jù)經(jīng)過keyBy發(fā)生了數(shù)據(jù)交換,數(shù)據(jù)會跨越分區(qū),因此無法將keyBy以及其后面的窗口聚合鏈接到一起。由于WindowAggregation的并行度是2,Sink的并行度為1,數(shù)據(jù)再次發(fā)生了交換,我們不能把WindowAggregation和Sink兩部分鏈接到一起。1.2節(jié)中提到,Sink的并行度是人為設(shè)置為1,如果我們把Sink的并行度也設(shè)置為2,那么是可以讓這兩個算子鏈接到一起的。
默認(rèn)情況下,Flink會盡量將更多的子任務(wù)鏈接在一起,這樣能減少一些不必要的數(shù)據(jù)傳輸開銷。但一個子任務(wù)有超過一個輸入或發(fā)生數(shù)據(jù)交換時,鏈接就無法建立。兩個算子能夠鏈接到一起是有一些規(guī)則的,感興趣的讀者可以閱讀Flink源碼中org.apache.flink.streaming.api.graph.StreamingJobGraphGenerator中的isChainable方法。StreamingJobGraphGenerator類的作用是將StreamGraph轉(zhuǎn)換為JobGraph。
盡管將算子鏈接到一起會降低一些傳輸開銷,但是也有一些情況并不需要太多鏈接。比如,有時候我們需要將一個非常長的算子鏈拆開,這樣我們就可以將原來集中在一個線程中的計算拆分到多個線程中來并行計算。Flink允許開發(fā)者手動配置是否啟用算子鏈,或者對哪些算子使用算子鏈。
2.4 任務(wù)槽位與計算資源
任務(wù)槽位
根據(jù)前文的介紹,我們已經(jīng)了解到TaskManager負(fù)責(zé)具體的任務(wù)執(zhí)行。TaskManager是一個JVM進(jìn)程,在TaskManager中可以并行運行多個Task。在程序執(zhí)行之前,經(jīng)過優(yōu)化,部分子任務(wù)被鏈接在一起,組成一個Task。每個Task是一個線程,需要TaskManager為其分配相應(yīng)的資源,TaskManager使用任務(wù)槽位給Task分配資源。
在解釋Flink任務(wù)槽位的概念前,我們先回顧一下進(jìn)程與線程的概念。在操作系統(tǒng)層面,進(jìn)程(Process)是進(jìn)行資源分配和調(diào)度的一個獨立單位,線程(Thread)是CPU調(diào)度的基本單位。比如,我們常用的Office Word軟件,在啟動后就占用操作系統(tǒng)的一個進(jìn)程。Windows上可以使用任務(wù)管理器來查看當(dāng)前活躍的進(jìn)程,Linux上可以使用top命令來查看。線程是進(jìn)程的一個子集,一個線程一般專注于處理一些特定任務(wù),不獨立擁有系統(tǒng)資源,只擁有一些運行中必要的資源,如程序計數(shù)器。一個進(jìn)程至少有一個線程,也可以有多個線程。多線程場景下,每個線程都處理一小個任務(wù),多個線程以高并發(fā)的方式同時處理多個小任務(wù),可以提高處理能力。
回到Flink的槽位分配機制上,一個TaskManager是一個進(jìn)程,TaskManager可以管理一至多個Task,每個Task是一個線程,占用一個槽位。每個槽位的資源是整個TaskManager資源的子集,比如這里的TaskManager下有3個槽位,每個槽位占用TaskManager所管理的1/3的內(nèi)存,第一個槽位中的Task不會與第二個槽位中的Task互相爭搶內(nèi)存資源。注意,在分配資源時,Flink并沒有將CPU資源明確分配給各個槽位。
圖 8 Task Slot與Task Manager
假設(shè)我們給WordCount程序分配兩個TaskManager,每個TaskManager又分配3個槽位,所以總共是6個槽位。結(jié)合圖 7中對這個作業(yè)的并行度設(shè)置,整個作業(yè)被劃分為5個Task,使用5個線程,這5個線程可以按照圖 8所示的方式分配到6個槽位中。
Flink允許用戶設(shè)置TaskManager中槽位的數(shù)目,這樣用戶就可以確定以怎樣的粒度將任務(wù)做相互隔離。如果每個TaskManager只包含一個槽位,那么運行在該槽位內(nèi)的任務(wù)將獨享JVM。如果TaskManager包含多個槽位,那么多個槽位內(nèi)的任務(wù)可以共享JVM資源,比如共享TCP連接、心跳信息、部分?jǐn)?shù)據(jù)結(jié)構(gòu)等。官方建議將槽位數(shù)目設(shè)置為TaskManager下可用的CPU核心數(shù),那么平均下來,每個槽位都能平均獲得1個CPU核心。
槽位共享
圖 8中展示了任務(wù)的一種資源分配方式,默認(rèn)情況下, Flink還提供了一種槽位共享(Slot Sharing)的優(yōu)化機制,進(jìn)一步優(yōu)化數(shù)據(jù)傳輸開銷,充分利用計算資源。將圖 8中的任務(wù)做槽位共享優(yōu)化后,結(jié)果如圖 9所示。
圖 9 槽位共享示意圖
開啟槽位共享后,Flink允許多個任務(wù)共享一個槽位。如圖 9中最左側(cè)的數(shù)據(jù)流,一個作業(yè)從Source到Sink的所有子任務(wù)都可以放置在一個槽位中,這樣數(shù)據(jù)交換成本更低。而且,對于一個數(shù)據(jù)流圖來說,Source、FlatMap等算子的計算量相對不大,WindowAggregation算子的計算量比較大,計算量較大的算子子任務(wù)與計算量較小的算子子任務(wù)可以互補,騰出更多的槽位,分配給更多Task,這樣可以更好地利用資源。如果不開啟槽位共享,如圖8所示,計算量小的Source、FlatMap算子子任務(wù)獨占槽位,造成一定的資源浪費。
圖 10 槽位共享后,增大并行度,可以部署更多算子實例
圖 8中的方式共占用5個槽位,支持槽位共享后,圖 9只占用2個槽位。為了充分利用空槽位,剩余的4個空槽位可以分配給別的作業(yè),也可以通過修改并行度來分配給這個作業(yè)。例如,這個作業(yè)的輸入數(shù)據(jù)量非常大,我們可以把并行度設(shè)為6,更多的算子實例會將這些槽位填充,如圖10所示。
綜上,Flink的一個槽位中可能運行一個算子子任務(wù)、也可能是被鏈接的多個子任務(wù),或者是多個子任務(wù)共享槽位,具體這個槽位上運行哪些計算由算子鏈和槽位共享兩個優(yōu)化措施決定。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的flink运行原理_浅谈Flink分布式运行时和数据流图的并行化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 集群节点数和分片数关系_完全二叉树的节点
- 下一篇: 仓库移动_移动式仓库、检修作业平台、储油