Flink架構(gòu)和原理介紹

概念

Apache Flink 是一個(gè)在有界數(shù)據(jù)流和無界數(shù)據(jù)流上進(jìn)行有狀態(tài)計(jì)算分布式處理引擎和框架。Flink 設(shè)計(jì)旨在所有常見的集群環(huán)境中運(yùn)行,以任意規(guī)模和內(nèi)存級(jí)速度執(zhí)行計(jì)算。

特點(diǎn)

Apache Flink是一個(gè)面向分布式數(shù)據(jù)流處理和批量數(shù)據(jù)處理的開源計(jì)算平臺(tái),它能夠基于同一個(gè)Flink運(yùn)行時(shí),提供支持流處理和批處理兩種類型應(yīng)用的功能。

現(xiàn)有的開源計(jì)算方案,會(huì)把流處理和批處理作為兩種不同的應(yīng)用類型,因?yàn)樗鼈兯峁┑腟LA(Service-Level-Aggreement)是完全不相同的:流處理一般需要支持低延遲、Exactly-once保證,而批處理需要支持高吞吐、高效處理。

Flink從另一個(gè)視角看待流處理和批處理,將二者統(tǒng)一起來:Flink是完全支持流處理,也就是說作為流處理看待時(shí)輸入數(shù)據(jù)流是無界的;批處理被作為一種特殊的流處理,只是它的輸入數(shù)據(jù)流被定義為有界的。

技術(shù)棧

Flink首先支持Local的執(zhí)行環(huán)境,所有模塊組件都可以運(yùn)行在同一個(gè)JVM進(jìn)程中,主要是方便開發(fā)調(diào)試,使用者在開發(fā)Flink應(yīng)用時(shí)可以在IDE環(huán)境中方便的本地運(yùn)行或是設(shè)置斷點(diǎn)進(jìn)行代碼調(diào)試。此外Flink支持Standalone模式進(jìn)行分布式部署,F(xiàn)link的JobManager和TaskManager可以部署在多臺(tái)節(jié)點(diǎn)上,組成一個(gè)集群,管理集群資源,執(zhí)行分布式任務(wù)。同時(shí)Flink也可以委托YARN進(jìn)行資源管理,F(xiàn)link的Job通過YARN申請(qǐng)資源。最后,F(xiàn)link也支持Google和Amazon的公有云平臺(tái),F(xiàn)link的Job可以直接提交到公有云上執(zhí)行。用戶開發(fā)的同一個(gè)Flink業(yè)務(wù)邏輯,無需任何修改,可隨時(shí)遷移到不同的執(zhí)行環(huán)境執(zhí)行。

Flink首先支持Local的執(zhí)行環(huán)境,所有模塊組件都可以運(yùn)行在同一個(gè)JVM進(jìn)程中,主要是方便開發(fā)調(diào)試,使用者在開發(fā)Flink應(yīng)用時(shí)可以在IDE環(huán)境中方便的本地運(yùn)行或是設(shè)置斷點(diǎn)進(jìn)行代碼調(diào)試。此外Flink支持Standalone模式進(jìn)行分布式部署,F(xiàn)link的JobManager和TaskManager可以部署在多臺(tái)節(jié)點(diǎn)上,組成一個(gè)集群,管理集群資源,執(zhí)行分布式任務(wù)。同時(shí)Flink也可以委托YARN進(jìn)行資源管理,F(xiàn)link的Job通過YARN申請(qǐng)資源。最后,F(xiàn)link也支持Google和Amazon的公有云平臺(tái),F(xiàn)link的Job可以直接提交到公有云上執(zhí)行。用戶開發(fā)的同一個(gè)Flink業(yè)務(wù)邏輯,無需任何修改,可隨時(shí)遷移到不同的執(zhí)行環(huán)境執(zhí)行。

架構(gòu)

https://nightlies.apache.org/flink/flink-docs-release-1.14/zh/docs/concepts/flink-architecture/

Flink 是一個(gè)分布式系統(tǒng),需要有效分配和管理計(jì)算資源才能執(zhí)行流應(yīng)用程序。它集成了所有常見的集群資源管理器,例如Hadoop YARN,但也可以設(shè)置作為獨(dú)立集群甚至庫(kù)運(yùn)行。

Flink 運(yùn)行時(shí)由兩種類型的進(jìn)程組成:一個(gè) JobManager 和一個(gè)或者多個(gè) TaskManager。


Client?不是運(yùn)行時(shí)和程序執(zhí)行的一部分,而是用于準(zhǔn)備數(shù)據(jù)流并將其發(fā)送給 JobManager。之后,客戶端可以斷開連接(分離模式),或保持連接來接收進(jìn)程報(bào)告(附加模式)。客戶端可以作為觸發(fā)執(zhí)行 Java/Scala 程序的一部分運(yùn)行,也可以在命令行進(jìn)程./bin/flink run ...中運(yùn)行。

可以通過多種方式啟動(dòng) JobManager 和 TaskManager:直接在機(jī)器上作為standalone 集群啟動(dòng)、在容器中啟動(dòng)、或者通過YARN等資源框架管理并啟動(dòng)。TaskManager 連接到 JobManagers,宣布自己可用,并被分配工作。

JobManager?#

JobManager?具有許多與協(xié)調(diào) Flink 應(yīng)用程序的分布式執(zhí)行有關(guān)的職責(zé):它決定何時(shí)調(diào)度下一個(gè) task(或一組 task)、對(duì)完成的 task 或執(zhí)行失敗做出反應(yīng)、協(xié)調(diào) checkpoint、并且協(xié)調(diào)從失敗中恢復(fù)等等。這個(gè)進(jìn)程由三個(gè)不同的組件組成:

ResourceManager

ResourceManager?負(fù)責(zé) Flink 集群中的資源提供、回收、分配 - 它管理?task slots,這是 Flink 集群中資源調(diào)度的單位(請(qǐng)參考TaskManagers)。Flink 為不同的環(huán)境和資源提供者(例如 YARN、Kubernetes 和 standalone 部署)實(shí)現(xiàn)了對(duì)應(yīng)的 ResourceManager。在 standalone 設(shè)置中,ResourceManager 只能分配可用 TaskManager 的 slots,而不能自行啟動(dòng)新的 TaskManager。

Dispatcher

Dispatcher?提供了一個(gè) REST 接口,用來提交 Flink 應(yīng)用程序執(zhí)行,并為每個(gè)提交的作業(yè)啟動(dòng)一個(gè)新的 JobMaster。它還運(yùn)行 Flink WebUI 用來提供作業(yè)執(zhí)行信息。

JobMaster

JobMaster?負(fù)責(zé)管理單個(gè)JobGraph的執(zhí)行。Flink 集群中可以同時(shí)運(yùn)行多個(gè)作業(yè),每個(gè)作業(yè)都有自己的 JobMaster。

始終至少有一個(gè) JobManager。高可用(HA)設(shè)置中可能有多個(gè) JobManager,其中一個(gè)始終是?leader,其他的則是?standby(請(qǐng)參考?高可用(HA))。

TaskManagers?#

TaskManager(也稱為?worker)執(zhí)行作業(yè)流的 task,并且緩存和交換數(shù)據(jù)流。

必須始終至少有一個(gè) TaskManager。在 TaskManager 中資源調(diào)度的最小單位是 task?slot。TaskManager 中 task slot 的數(shù)量表示并發(fā)處理 task 的數(shù)量。請(qǐng)注意一個(gè) task slot 中可以執(zhí)行多個(gè)算子(請(qǐng)參考Tasks 和算子鏈)。

Tasks 和算子鏈?#

對(duì)于分布式執(zhí)行,F(xiàn)link 將算子的 subtasks?鏈接成?tasks。每個(gè) task 由一個(gè)線程執(zhí)行。將算子鏈接成 task 是個(gè)有用的優(yōu)化:它減少線程間切換、緩沖的開銷,并且減少延遲的同時(shí)增加整體吞吐量。鏈行為是可以配置的;請(qǐng)參考鏈文檔以獲取詳細(xì)信息。

下圖中樣例數(shù)據(jù)流用 5 個(gè) subtask 執(zhí)行,因此有 5 個(gè)并行線程。

Task Slots 和資源?#

每個(gè) worker(TaskManager)都是一個(gè)?JVM 進(jìn)程,可以在單獨(dú)的線程中執(zhí)行一個(gè)或多個(gè) subtask。為了控制一個(gè) TaskManager 中接受多少個(gè) task,就有了所謂的?task slots(至少一個(gè))。

每個(gè)?task slot?代表 TaskManager 中資源的固定子集。例如,具有 3 個(gè) slot 的 TaskManager,會(huì)將其托管內(nèi)存 1/3 用于每個(gè) slot。分配資源意味著 subtask 不會(huì)與其他作業(yè)的 subtask 競(jìng)爭(zhēng)托管內(nèi)存,而是具有一定數(shù)量的保留托管內(nèi)存。注意此處沒有 CPU 隔離;當(dāng)前 slot 僅分離 task 的托管內(nèi)存。

通過調(diào)整 task slot 的數(shù)量,用戶可以定義 subtask 如何互相隔離。每個(gè) TaskManager 有一個(gè) slot,這意味著每個(gè) task 組都在單獨(dú)的 JVM 中運(yùn)行(例如,可以在單獨(dú)的容器中啟動(dòng))。具有多個(gè) slot 意味著更多 subtask 共享同一 JVM。同一 JVM 中的 task 共享 TCP 連接(通過多路復(fù)用)和心跳信息。它們還可以共享數(shù)據(jù)集和數(shù)據(jù)結(jié)構(gòu),從而減少了每個(gè) task 的開銷。


默認(rèn)情況下,F(xiàn)link 允許 subtask 共享 slot,即便它們是不同的 task 的 subtask,只要是來自于同一作業(yè)即可。結(jié)果就是一個(gè) slot 可以持有整個(gè)作業(yè)管道。允許?slot 共享有兩個(gè)主要優(yōu)點(diǎn):

Flink 集群所需的 task slot 和作業(yè)中使用的最大并行度恰好一樣。無需計(jì)算程序總共包含多少個(gè) task(具有不同并行度)。

容易獲得更好的資源利用。如果沒有 slot 共享,非密集 subtask(source/map())將阻塞和密集型 subtask(window) 一樣多的資源。通過 slot 共享,我們示例中的基本并行度從 2 增加到 6,可以充分利用分配的資源,同時(shí)確保繁重的 subtask 在 TaskManager 之間公平分配。


Flink 應(yīng)用程序執(zhí)行?#

Flink 應(yīng)用程序?是從其?main()?方法產(chǎn)生的一個(gè)或多個(gè) Flink 作業(yè)的任何用戶程序。這些作業(yè)的執(zhí)行可以在本地 JVM(LocalEnvironment)中進(jìn)行,或具有多臺(tái)機(jī)器的集群的遠(yuǎn)程設(shè)置(RemoteEnvironment)中進(jìn)行。對(duì)于每個(gè)程序,ExecutionEnvironment?提供了一些方法來控制作業(yè)執(zhí)行(例如設(shè)置并行度)并與外界交互(請(qǐng)參考?Flink 程序剖析?)。

Flink 應(yīng)用程序的作業(yè)可以被提交到長(zhǎng)期運(yùn)行的?Flink Session 集群、專用的?Flink Job 集群?或?Flink Application 集群。這些選項(xiàng)之間的差異主要與集群的生命周期和資源隔離保證有關(guān)。

Flink Session 集群?#

集群生命周期:在 Flink Session 集群中,客戶端連接到一個(gè)預(yù)先存在的、長(zhǎng)期運(yùn)行的集群,該集群可以接受多個(gè)作業(yè)提交。即使所有作業(yè)完成后,集群(和 JobManager)仍將繼續(xù)運(yùn)行直到手動(dòng)停止 session 為止。因此,F(xiàn)link Session 集群的壽命不受任何 Flink 作業(yè)壽命的約束。

資源隔離:TaskManager slot 由 ResourceManager 在提交作業(yè)時(shí)分配,并在作業(yè)完成時(shí)釋放。由于所有作業(yè)都共享同一集群,因此在集群資源方面存在一些競(jìng)爭(zhēng) — 例如提交工作階段的網(wǎng)絡(luò)帶寬。此共享設(shè)置的局限性在于,如果 TaskManager 崩潰,則在此 TaskManager 上運(yùn)行 task 的所有作業(yè)都將失?。活愃频?,如果 JobManager 上發(fā)生一些致命錯(cuò)誤,它將影響集群中正在運(yùn)行的所有作業(yè)。

其他注意事項(xiàng):擁有一個(gè)預(yù)先存在的集群可以節(jié)省大量時(shí)間申請(qǐng)資源和啟動(dòng) TaskManager。有種場(chǎng)景很重要,作業(yè)執(zhí)行時(shí)間短并且啟動(dòng)時(shí)間長(zhǎng)會(huì)對(duì)端到端的用戶體驗(yàn)產(chǎn)生負(fù)面的影響 — 就像對(duì)簡(jiǎn)短查詢的交互式分析一樣,希望作業(yè)可以使用現(xiàn)有資源快速執(zhí)行計(jì)算。

以前,F(xiàn)link Session 集群也被稱為?session 模式下的 Flink 集群。

Flink Job 集群?#

集群生命周期:在 Flink Job 集群中,可用的集群管理器(例如 YARN)用于為每個(gè)提交的作業(yè)啟動(dòng)一個(gè)集群,并且該集群僅可用于該作業(yè)。在這里,客戶端首先從集群管理器請(qǐng)求資源啟動(dòng) JobManager,然后將作業(yè)提交給在這個(gè)進(jìn)程中運(yùn)行的 Dispatcher。然后根據(jù)作業(yè)的資源請(qǐng)求惰性的分配 TaskManager。一旦作業(yè)完成,F(xiàn)link Job 集群將被拆除。

資源隔離:JobManager 中的致命錯(cuò)誤僅影響在 Flink Job 集群中運(yùn)行的一個(gè)作業(yè)。

其他注意事項(xiàng):由于 ResourceManager 必須應(yīng)用并等待外部資源管理組件來啟動(dòng) TaskManager 進(jìn)程和分配資源,因此 Flink Job 集群更適合長(zhǎng)期運(yùn)行、具有高穩(wěn)定性要求且對(duì)較長(zhǎng)的啟動(dòng)時(shí)間不敏感的大型作業(yè)。

以前,F(xiàn)link Job 集群也被稱為?job (or per-job) 模式下的 Flink 集群。

Kubernetes 不支持 Flink Job 集群。 請(qǐng)參考?Standalone Kubernetes?和?Native Kubernetes。

Flink Application 集群?#

集群生命周期:Flink Application 集群是專用的 Flink 集群,僅從 Flink 應(yīng)用程序執(zhí)行作業(yè),并且?main()方法在集群上而不是客戶端上運(yùn)行。提交作業(yè)是一個(gè)單步驟過程:無需先啟動(dòng) Flink 集群,然后將作業(yè)提交到現(xiàn)有的 session 集群;相反,將應(yīng)用程序邏輯和依賴打包成一個(gè)可執(zhí)行的作業(yè) JAR 中,并且集群入口(ApplicationClusterEntryPoint)負(fù)責(zé)調(diào)用?main()方法來提取 JobGraph。例如,這允許你像在 Kubernetes 上部署任何其他應(yīng)用程序一樣部署 Flink 應(yīng)用程序。因此,F(xiàn)link Application 集群的壽命與 Flink 應(yīng)用程序的壽命有關(guān)。

資源隔離:在 Flink Application 集群中,ResourceManager 和 Dispatcher 作用于單個(gè)的 Flink 應(yīng)用程序,相比于 Flink Session 集群,它提供了更好的隔離。

Flink Job 集群可以看做是 Flink Application 集群”客戶端運(yùn)行“的替代方案。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容