簡(jiǎn)介
Flink運(yùn)行時(shí)主要角色有兩個(gè):JobManager和TaskManager,無(wú)論是standalone集群,flink on yarn都是要啟動(dòng)這兩個(gè)角色。JobManager主要是負(fù)責(zé)接受客戶端的job,調(diào)度job,協(xié)調(diào)checkpoint等。TaskManager執(zhí)行具體的Task。TaskManager為了對(duì)資源進(jìn)行隔離和增加允許的task數(shù),引入了slot的概念,這個(gè)slot對(duì)資源的隔離僅僅是對(duì)內(nèi)存進(jìn)行隔離,策略是均分,比如taskmanager的管理內(nèi)存是3GB,假如有兩個(gè)個(gè)slot,那么每個(gè)slot就僅僅有1.5GB內(nèi)存可用。Client這個(gè)角色主要是為job提交做些準(zhǔn)備工作,比如構(gòu)建jobgraph提交到j(luò)obmanager,提交完了可以立即退出,當(dāng)然也可以用client來(lái)監(jiān)控進(jìn)度。
Jobmanager和TaskManager之間通信類似于Spark 的早期版本,采用的是actor系統(tǒng)。如下圖
什么是task?
在spark中:
RDD中的一個(gè)分區(qū)對(duì)應(yīng)一個(gè)task,task是單個(gè)分區(qū)上最小的處理流程單元。被送到某個(gè)Executor上的工作單元,和hadoopMR中的MapTask和ReduceTask概念一樣,是運(yùn)行Application的基本單位,多個(gè)Task組成一個(gè)Stage
上述引入spark的task主要是想帶著大家搞明白,以下幾個(gè)概念:
Flink的并行度由什么決定的?
Flink的task是什么?
Flink的并行度由什么決定的?
這個(gè)很簡(jiǎn)單,F(xiàn)link每個(gè)算子都可以設(shè)置并行度,然后就是也可以設(shè)置全局并行度。
Api的設(shè)置
.map(new RollingAdditionMapper()).setParallelism(10)
全局配置在flink-conf.yaml文件中,parallelism.default,默認(rèn)是1:可以設(shè)置默認(rèn)值大一點(diǎn)
Flink的task是什么?
按理說(shuō)應(yīng)該是每個(gè)算子的一個(gè)并行度實(shí)例就是一個(gè)subtask-在這里為了區(qū)分暫時(shí)叫做substask。那么,帶來(lái)很多問(wèn)題,由于flink的taskmanager運(yùn)行task的時(shí)候是每個(gè)task采用一個(gè)單獨(dú)的線程,這就會(huì)帶來(lái)很多線程切換開(kāi)銷,進(jìn)而影響吞吐量。為了減輕這種情況,flink進(jìn)行了優(yōu)化,也即對(duì)subtask進(jìn)行鏈?zhǔn)讲僮鳎準(zhǔn)讲僮鹘Y(jié)束之后得到的task,再作為一個(gè)調(diào)度執(zhí)行單元,放到一個(gè)線程里執(zhí)行。如下圖的,source/map 兩個(gè)算子進(jìn)行了鏈?zhǔn)剑籯eyby/window/apply有進(jìn)行了鏈?zhǔn)剑瑂ink單獨(dú)的一個(gè)。
說(shuō)明:圖中假設(shè)是source/map的并行度都是2,keyby/window/apply的并行度也都是2,sink的是1,總共task有五個(gè),最終需要五個(gè)線程。
默認(rèn)情況下,flink允許如果任務(wù)是不同的task的時(shí)候,允許任務(wù)共享slot,當(dāng)然,前提是必須在同一個(gè)job內(nèi)部。
結(jié)果就是,每個(gè)slot可以執(zhí)行job的一整個(gè)pipeline,如上圖。這樣做的好處主要有以下幾點(diǎn):
1.Flink 集群所需的taskslots數(shù)與job中最高的并行度一致。也就是說(shuō)我們不需要再去計(jì)算一個(gè)程序總共會(huì)起多少個(gè)task了。
2.更容易獲得更充分的資源利用。如果沒(méi)有slot共享,那么非密集型操作source/flatmap就會(huì)占用同密集型操作 keyAggregation/sink 一樣多的資源。如果有slot共享,將基線的2個(gè)并行度增加到6個(gè),能充分利用slot資源,同時(shí)保證每個(gè)TaskManager能平均分配到重的subtasks,比如keyby/window/apply操作就會(huì)均分到申請(qǐng)的所有slot里,這樣slot的負(fù)載就均衡了。
鏈?zhǔn)降脑瓌t,也即是什么情況下才會(huì)對(duì)task進(jìn)行鏈?zhǔn)讲僮髂兀亢?jiǎn)單梗概一下:
上下游的并行度一致
下游節(jié)點(diǎn)的入度為1 (也就是說(shuō)下游節(jié)點(diǎn)沒(méi)有來(lái)自其他節(jié)點(diǎn)的輸入)
上下游節(jié)點(diǎn)都在同一個(gè) slot group 中(下面會(huì)解釋 slot group)
下游節(jié)點(diǎn)的 chain 策略為 ALWAYS(可以與上下游鏈接,map、flatmap、filter等默認(rèn)是ALWAYS)
上游節(jié)點(diǎn)的 chain 策略為 ALWAYS 或 HEAD(只能與下游鏈接,不能與上游鏈接,Source默認(rèn)是HEAD)
兩個(gè)節(jié)點(diǎn)間數(shù)據(jù)分區(qū)方式是 forward(參考理解數(shù)據(jù)流的分區(qū))
用戶沒(méi)有禁用 chain
slot和parallelism
1.slot是指taskmanager的并發(fā)執(zhí)行能力
在hadoop 1.x 版本中也有slot的概念,有興趣的讀者可以了解一下
taskmanager.numberOfTaskSlots:3
每一個(gè)taskmanager中的分配3個(gè)TaskSlot,3個(gè)taskmanager一共有9個(gè)TaskSlot
2.parallelism是指taskmanager實(shí)際使用的并發(fā)能力
parallelism.default:1
運(yùn)行程序默認(rèn)的并行度為1,9個(gè)TaskSlot只用了1個(gè),有8個(gè)空閑。設(shè)置合適的并行度才能提高效率。
3.parallelism是可配置、可指定的
1.可以通過(guò)修改$FLINK_HOME/conf/flink-conf.yaml文件的方式更改并行度
2.可以通過(guò)設(shè)置$FLINK_HOME/bin/flink 的-p參數(shù)修改并行度
3.可以通過(guò)設(shè)置executionEnvironmentk的方法修改并行度
4.可以通過(guò)設(shè)置flink的編程API修改過(guò)并行度
5.這些并行度設(shè)置優(yōu)先級(jí)從低到高排序,排序?yàn)閍pi>env>p>file.
6.設(shè)置合適的并行度,能提高運(yùn)算效率
7.parallelism不能多與slot個(gè)數(shù)。
slot和parallelism總結(jié)
1.slot是靜態(tài)的概念,是指taskmanager具有的并發(fā)執(zhí)行能力
2.parallelism是動(dòng)態(tài)的概念,是指程序運(yùn)行時(shí)實(shí)際使用的并發(fā)能力
3.設(shè)置合適的parallelism能提高運(yùn)算效率,太多了和太少了都不行
4.設(shè)置parallelism有多中方式,優(yōu)先級(jí)為api>env>p>file