Flink on YARN的第三種部署模式:Application Mode

前言

短文狀態繼續。

長久以來,在YARN集羣中部署Flink作業有兩種模式,即Session Mode和Per-Job Mode,而在Flink 1.11版本中,又引入了第三種全新的模式:Application Mode。本文先回顧兩種傳統模式的做法與存在的問題,再簡要介紹Application Mode。

傳統部署模式

Session模式

Session模式是預分配資源的,也就是提前根據指定的資源參數初始化一個Flink集羣,並常駐在YARN系統中,擁有固定數量的JobManager和TaskManager(注意JobManager只有一個)。提交到這個集羣的作業可以直接運行,免去每次分配資源的overhead。但是Session的資源總量有限,多個作業之間又不是隔離的,故可能會造成資源的爭用;如果有一個TaskManager宕機,它上面承載着的所有作業也都會失敗。另外,啓動的作業越多,JobManager的負載也就越大。所以,Session模式一般用來部署那些對延遲非常敏感但運行時長較短的作業。

Per-Job模式

顧名思義,在Per-Job模式下,每個提交到YARN上的作業會各自形成單獨的Flink集羣,擁有專屬的JobManager和TaskManager。可見,以Per-Job模式提交作業的啓動延遲可能會較高,但是作業之間的資源完全隔離,一個作業的TaskManager失敗不會影響其他作業的運行,JobManager的負載也是分散開來的,不存在單點問題。當作業運行完成,與它關聯的集羣也就被銷燬,資源被釋放。所以,Per-Job模式一般用來部署那些長時間運行的作業。

存在的問題

上文所述Session模式和Per-Job模式可以用如下的簡圖表示,其中紅色、藍色和綠色的圖形代表不同的作業。

Deployer代表向YARN集羣發起部署請求的節點,一般來講在生產環境中,也總有這樣一個節點作爲所有作業的提交入口(即客戶端)。在main()方法開始執行直到env.execute()方法之前,客戶端也需要做一些工作,即:

  • 獲取作業所需的依賴項;
  • 通過執行環境分析並取得邏輯計劃,即StreamGraph→JobGraph;
  • 將依賴項和JobGraph上傳到集羣中。

只有在這些都完成之後,纔會通過env.execute()方法觸發Flink運行時真正地開始執行作業。試想,如果所有用戶都在Deployer上提交作業,較大的依賴會消耗更多的帶寬,而較複雜的作業邏輯翻譯成JobGraph也需要喫掉更多的CPU和內存,客戶端的資源反而會成爲瓶頸——不管Session還是Per-Job模式都存在此問題。爲了解決它,社區在傳統部署模式的基礎上實現了Application模式。

Application模式

此模式下的作業提交框圖如下。

可見,原本需要客戶端做的三件事被轉移到了JobManager裏,也就是說main()方法在集羣中執行(入口點位於ApplicationClusterEntryPoint),Deployer只需要負責發起部署請求了。另外,如果一個main()方法中有多個env.execute()/executeAsync()調用,在Application模式下,這些作業會被視爲屬於同一個應用,在同一個集羣中執行(如果在Per-Job模式下,就會啓動多個集羣)。可見,Application模式本質上是Session和Per-Job模式的折衷。

用Application模式提交作業的示例命令如下。

bin/flink run-application -t yarn-application \
-Djobmanager.memory.process.size=2048m \
-Dtaskmanager.memory.process.size=4096m \
-Dtaskmanager.numberOfTaskSlots=2 \
-Dparallelism.default=10 \
-Dyarn.application.name="MyFlinkApp" \
/path/to/my/flink-app/MyFlinkApp.jar

-t參數用來指定部署目標,目前支持YARN(yarn-application)和K8S(kubernetes-application)。-D參數則用來指定與作業相關的各項參數,具體可參見官方文檔

那麼如何解決傳輸依賴項造成的帶寬佔用問題呢?Flink作業必須的依賴是發行包flink-dist.jar,還有擴展庫(位於$FLINK_HOME/lib)和插件庫(位於$FLINK_HOME/plugin),我們將它們預先上傳到像HDFS這樣的共享存儲,再通過yarn.provided.lib.dirs參數指定存儲的路徑即可。

-Dyarn.provided.lib.dirs="hdfs://myhdfs/flink-common-deps/lib;hdfs://myhdfs/flink-common-deps/plugins"

這樣所有作業就不必各自上傳依賴,可以直接從HDFS拉取,並且YARN NodeManager也會緩存這些依賴,進一步加快作業的提交過程。同理,包含Flink作業的用戶JAR包也可以上傳到HDFS,並指定遠程路徑進行提交。

The End

民那晚安。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章