Apache Flink 進階教程(四):Flink on Yarn/K8s 原理剖析及實踐

本文內容出自 Apache Flink公開課系列
作者:周凱波(寶牛)

本文主要介紹 Flink on Yarn/K8s 的原理及應用實踐,文章將從 Flink 架構、Flink on Yarn 原理及實踐、Flink on Kubernetes 原理剖析三部分內容進行分享並對 Flink on Yarn/Kubernetes 中存在的部分問題進行了解答。

Flink 架構概覽

Flink 架構概覽–Job

在這裏插入圖片描述
用戶通過 DataStream API、DataSet API、SQL 和 Table API 編寫 Flink 任務,它會生成一個JobGraph。JobGraph 是由 source、map()、keyBy()/window()/apply() 和 Sink 等算子組成的。當 JobGraph 提交給 Flink 集羣后,能夠以 Local、Standalone、Yarn 和 Kubernetes 四種模式運行。

Flink 架構概覽–JobManager

在這裏插入圖片描述
JobManager的功能主要有:

  • 將 JobGraph 轉換成 Execution Graph,最終將 Execution Graph 拿來運行

  • Scheduler 組件負責 Task 的調度

  • Checkpoint Coordinator 組件負責協調整個任務的 Checkpoint,包括 Checkpoint 的開始和完成

  • 通過 Actor System 與 TaskManager 進行通信

  • 其它的一些功能,例如 Recovery Metadata,用於進行故障恢復時,可以從 Metadata 裏面讀取數據。

Flink 架構概覽–TaskManager

在這裏插入圖片描述
TaskManager 是負責具體任務的執行過程,在 JobManager 申請到資源之後開始啓動。TaskManager 裏面的主要組件有:

  • Memory & I/O Manager,即內存 I/O 的管理

  • Network Manager,用來對網絡方面進行管理

  • Actor system,用來負責網絡的通信

TaskManager 被分成很多個 TaskSlot,每個任務都要運行在一個 TaskSlot 裏面,TaskSlot 是調度資源裏的最小單位。
在這裏插入圖片描述
在介紹 Yarn 之前先簡單的介紹一下 Flink Standalone 模式,這樣有助於更好地瞭解 Yarn 和 Kubernetes 架構。

  • 在 Standalone 模式下,Master 和 TaskManager 可以運行在同一臺機器上,也可以運行在不同的機器上。

  • 在 Master 進程中,Standalone ResourceManager 的作用是對資源進行管理。當用戶通過 Flink Cluster Client 將 JobGraph 提交給 Master 時,JobGraph 先經過 Dispatcher。

  • 當 Dispatcher 收到客戶端的請求之後,生成一個 JobManager。接着 JobManager 進程向 Standalone ResourceManager 申請資源,最終再啓動 TaskManager。

  • TaskManager 啓動之後,會有一個註冊的過程,註冊之後 JobManager 再將具體的 Task 任務分發給這個 TaskManager 去執行。

以上就是一個 Standalone 任務的運行過程。

Flink 運行時相關組件

接下來總結一下 Flink 的基本架構和它在運行時的一些組件,具體如下:

  • Client:用戶通過 SQL 或者 API 的方式進行任務的提交,提交後會生成一個 JobGraph。

  • JobManager:JobManager 接受到用戶的請求之後,會對任務進行調度,並且申請資源啓動 TaskManager。

  • TaskManager:它負責一個具體 Task 的執行。TaskManager 向 JobManager 進行註冊,當 TaskManager 接收到 JobManager 分配的任務之後,開始執行具體的任務。

Flink on Yarn 原理及實踐

Yarn 架構原理–總覽

Yarn 模式在國內使用比較廣泛,基本上大多數公司在生產環境中都使用過 Yarn 模式。首先介紹一下 Yarn 的架構原理,因爲只有足夠了解 Yarn 的架構原理,才能更好的知道 Flink 是如何在 Yarn 上運行的。
在這裏插入圖片描述
Yarn 的架構原理如上圖所示,最重要的角色是 ResourceManager,主要用來負責整個資源的管理,Client 端是負責向 ResourceManager 提交任務。

用戶在 Client 端提交任務後會先給到 Resource Manager。Resource Manager 會啓動 Container,接着進一步啓動 Application Master,即對 Master 節點的啓動。當 Master 節點啓動之後,會向 Resource Manager 再重新申請資源,當 Resource Manager 將資源分配給 Application Master 之後,Application Master 再將具體的 Task 調度起來去執行。

Yarn 架構原理–組件

Yarn 集羣中的組件包括:

  • ResourceManager (RM):ResourceManager (RM)負責處理客戶端請求、啓動/監控 ApplicationMaster、監控 NodeManager、資源的分配與調度,包含 Scheduler 和 Applications Manager。

  • ApplicationMaster (AM):ApplicationMaster (AM)運行在 Slave 上,負責數據切分、申請資源和分配、任務監控和容錯。

  • NodeManager (NM):NodeManager (NM)運行在 Slave 上,用於單節點資源管理、AM/RM通信以及彙報狀態。

  • Container:Container 負責對資源進行抽象,包括內存、CPU、磁盤,網絡等資源。

Yarn 架構原理–交互

在這裏插入圖片描述
以在 Yarn 上運行 MapReduce 任務爲例來講解下 Yarn 架構的交互原理:

  • 首先,用戶編寫 MapReduce 代碼後,通過 Client 端進行任務提交

  • ResourceManager 在接收到客戶端的請求後,會分配一個 Container 用來啓動 ApplicationMaster,並通知 NodeManager 在這個 Container 下啓動 ApplicationMaster。

  • ApplicationMaster 啓動後,向 ResourceManager 發起註冊請求。接着 ApplicationMaster 向 ResourceManager 申請資源。根據獲取到的資源,和相關的 NodeManager 通信,要求其啓動程序。

  • 一個或者多個 NodeManager 啓動 Map/Reduce Task。

  • NodeManager 不斷彙報 Map/Reduce Task 狀態和進展給 ApplicationMaster。

  • 當所有 Map/Reduce Task 都完成時,ApplicationMaster 向 ResourceManager 彙報任務完成,並註銷自己。

Flink on Yarn–Per Job

在這裏插入圖片描述
Flink on Yarn 中的 Per Job 模式是指每次提交一個任務,然後任務運行完成之後資源就會被釋放。在瞭解了 Yarn 的原理之後,Per Job 的流程也就比較容易理解了,具體如下:

  • 首先 Client 提交 Yarn App,比如 JobGraph 或者 JARs。

  • 接下來 Yarn 的 ResourceManager 會申請第一個 Container。這個 Container 通過 Application Master 啓動進程,Application Master 裏面運行的是 Flink 程序,即 Flink-Yarn ResourceManager 和 JobManager。

  • 最後 Flink-Yarn ResourceManager 向 Yarn ResourceManager 申請資源。當分配到資源後,啓動 TaskManager。TaskManager 啓動後向 Flink-Yarn ResourceManager 進行註冊,註冊成功後 JobManager 就會分配具體的任務給 TaskManager 開始執行。

Flink on Yarn–Session

在這裏插入圖片描述
在 Per Job 模式中,執行完任務後整個資源就會釋放,包括 JobManager、TaskManager 都全部退出。而 Session 模式則不一樣,它的 Dispatcher 和 ResourceManager 是可以複用的。Session 模式下,當 Dispatcher 在收到請求之後,會啓動 JobManager(A),讓 JobManager(A) 來完成啓動 TaskManager,接着會啓動 JobManager(B) 和對應的 TaskManager 的運行。當 A、B 任務運行完成後,資源並不會釋放。Session 模式也稱爲多線程模式,其特點是資源會一直存在不會釋放,多個 JobManager 共享一個 Dispatcher,而且還共享 Flink-YARN ResourceManager。

Session 模式和 Per Job 模式的應用場景不一樣。Per Job 模式比較適合那種對啓動時間不敏感,運行時間較長的任務。Seesion 模式適合短時間運行的任務,一般是批處理任務。若用 Per Job 模式去運行短時間的任務,那就需要頻繁的申請資源,運行結束後,還需要資源釋放,下次還需再重新申請資源才能運行。顯然,這種任務會頻繁啓停的情況不適用於 Per Job 模式,更適合用 Session 模式。

Yarn 模式特點

Yarn 模式的優點有:

  • 資源的統一管理和調度。Yarn 集羣中所有節點的資源(內存、CPU、磁盤、網絡等)被抽象爲 Container。計算框架需要資源進行運算任務時需要向 Resource Manager 申請 Container,YARN 按照特定的策略對資源進行調度和進行 Container 的分配。Yarn 模式能通過多種任務調度策略來利用提高集羣資源利用率。例如 FIFO Scheduler、Capacity Scheduler、Fair Scheduler,並能設置任務優先級。

  • 資源隔離:Yarn 使用了輕量級資源隔離機制 Cgroups 進行資源隔離以避免相互干擾,一旦 Container 使用的資源量超過事先定義的上限值,就將其殺死。

  • 自動 failover 處理。例如 Yarn NodeManager 監控、Yarn ApplicationManager 異常恢復。

Yarn 模式雖然有不少優點,但是也有諸多缺點,例如運維部署成本較高,靈活性不夠

Flink on Yarn 實踐

關於 Flink on Yarn 的實踐在 本站上面有很多課程,例如:《Flink 安裝部署、環境配置及運行應用程序》《客戶端操作》都是基於 Yarn 進行講解的,這裏就不再贅述。

Flink on Kubernetes 原理剖析

Kubernetes 是 Google 開源的容器集羣管理系統,其提供應用部署、維護、擴展機制等功能,利用 Kubernetes 能方便地管理跨機器運行容器化的應用。Kubernetes 和 Yarn 相比,相當於下一代的資源管理系統,但是它的能力遠遠不止這些。

Kubernetes–基本概念

Kubernetes(k8s)中的 Master 節點,負責管理整個集羣,含有一個集羣的資源數據訪問入口,還包含一個 Etcd 高可用鍵值存儲服務。Master 中運行着 API Server,Controller Manager 及 Scheduler 服務。

Node 爲集羣的一個操作單元,是 Pod 運行的宿主機。Node 節點裏包含一個 agent 進程,能夠維護和管理該 Node 上的所有容器的創建、啓停等。Node 還含有一個服務端 kube-proxy,用於服務發現、反向代理和負載均衡。Node 底層含有 docker engine,docker 引擎主要負責本機容器的創建和管理工作。

Pod 運行於 Node 節點上,是若干相關容器的組合。在 K8s 裏面 Pod 是創建、調度和管理的最小單位。

Kubernetes–架構圖

在這裏插入圖片描述
Kubernetes 的架構如圖所示,從這個圖裏面能看出 Kubernetes 的整個運行過程。

  • API Server 相當於用戶的一個請求入口,用戶可以提交命令給 Etcd,這時會將這些請求存儲到 Etcd 裏面去。

  • Etcd 是一個鍵值存儲,負責將任務分配給具體的機器,在每個節點上的 Kubelet 會找到對應的 container 在本機上運行。

  • 用戶可以提交一個 Replication Controller 資源描述,Replication Controller 會監視集羣中的容器並保持數量;用戶也可以提交 service 描述文件,並由 kube proxy 負責具體工作的流量轉發。

Kubernetes–核心概念

Kubernetes 中比較重要的概念有:

  • Replication Controller (RC) 用來管理 Pod 的副本。RC 確保任何時候 Kubernetes 集羣中有指定數量的 pod 副本(replicas) 在運行, 如果少於指定數量的 pod 副本,RC 會啓動新的 Container,反之會殺死多餘的以保證數量不變。

  • Service 提供了一個統一的服務訪問入口以及服務代理和發現機制

  • Persistent Volume(PV) 和 Persistent Volume Claim(PVC) 用於數據的持久化存儲。

  • ConfigMap 是指存儲用戶程序的配置文件,其後端存儲是基於 Etcd。

Flink on Kubernetes–架構

在這裏插入圖片描述
Flink on Kubernetes 的架構如圖所示,Flink 任務在 Kubernetes 上運行的步驟有:

  • 首先往 Kubernetes 集羣提交了資源描述文件後,會啓動 Master 和 Worker 的 container。

  • Master Container 中會啓動 Flink Master Process,包含 Flink-Container ResourceManager、JobManager 和 Program Runner。

  • Worker Container 會啓動 TaskManager,並向負責資源管理的 ResourceManager 進行註冊,註冊完成之後,由 JobManager 將具體的任務分給 Container,再由 Container 去執行。

  • 需要說明的是,在 Flink 裏的 Master 和 Worker 都是一個鏡像,只是腳本的命令不一樣,通過參數來選擇啓動 master 還是啓動 Worker。

Flink on Kubernetes–JobManager

JobManager 的執行過程分爲兩步:

  • 首先,JobManager 通過 Deployment 進行描述,保證 1 個副本的 Container 運行 JobManager,可以定義一個標籤,例如 flink-jobmanager。

  • 其次,還需要定義一個 JobManager Service,通過 service name 和 port 暴露 JobManager 服務,通過標籤選擇對應的 pods。

Flink on Kubernetes–TaskManager

TaskManager 也是通過 Deployment 來進行描述,保證 n 個副本的 Container 運行 TaskManager,同時也需要定義一個標籤,例如 flink-taskmanager。

對於 JobManager 和 TaskManager 運行過程中需要的一些配置文件,如:flink-conf.yaml、hdfs-site.xml、core-site.xml,可以通過將它們定義爲 ConfigMap 來實現配置的傳遞和讀取。

Flink on Kubernetes–交互

在這裏插入圖片描述
整個交互的流程比較簡單,用戶往 Kubernetes 集羣提交定義好的資源描述文件即可,例如 deployment、configmap、service 等描述。後續的事情就交給 Kubernetes 集羣自動完成。Kubernetes 集羣會按照定義好的描述來啓動 pod,運行用戶程序。各個組件的具體工作如下:

  • Service: 通過標籤(label selector)找到 job manager 的 pod 暴露服務。

  • Deployment:保證 n 個副本的 container 運行 JM/TM,應用升級策略。

  • ConfigMap:在每個 pod 上通過掛載 /etc/flink 目錄,包含 flink-conf.yaml 內容。

Flink on Kubernetes–實踐

接下來就講一下 Flink on Kubernetes 的實踐篇,即 K8s 上是怎麼運行任務的。

Session Cluster

•Session Cluster
    •啓動
        •kubectl create -f jobmanager-service.yaml
        •kubectl create -f jobmanager-deployment.yaml
        •kubectl create -f taskmanager-deployment.yaml
    •Submit job
        •kubectl port-forward service/flink-jobmanager 8081:8081
        •bin/flink run -d -m localhost:8081 ./examples/streaming/TopSpeedWindowing.jar
    •停止
        •kubectl delete -f jobmanager-deployment.yaml
        •kubectl delete -f taskmanager-deployment.yaml
        •kubectl delete -f  jobmanager-service.yaml

首先啓動 Session Cluster,執行上述三條啓動命令就可以將 Flink 的 JobManager-service、jobmanager-deployment、taskmanager-deployment 啓動起來。啓動完成之後用戶可以通過接口進行訪問,然後通過端口進行提交任務。若想銷燬集羣,直接用 kubectl delete 即可,整個資源就可以銷燬。
在這裏插入圖片描述
Flink 官方提供的例子如圖所示
圖中左側爲 jobmanager-deployment.yaml 配置,右側爲 taskmanager-deployment.yaml 配置。

在 jobmanager-deployment.yaml 配置中,代碼的第一行爲 apiVersion,apiVersion 是API 的一個版本號,版本號用的是 extensions/vlbetal 版本。資源類型爲 Deployment,元數據 metadata 的名爲 flink-jobmanager,spec 中含有副本數爲 1 的 replicas,labels 標籤用於 pod 的選取。containers 的鏡像名爲 jobmanager,containers 包含從公共 docker 倉庫下載的 image,當然也可以使用公司內部的私有倉庫。args 啓動參數用於決定啓動的是 jobmanager 還是 taskmanager;ports 是服務端口,常見的服務端口爲 8081 端口;env 是定義的環境變量,會傳遞給具體的啓動腳本。

右圖爲 taskmanager-deployment.yaml 配置,taskmanager-deployment.yaml 配置與 jobmanager-deployment.yaml 相似,但 taskmanager-deployment.yaml 的副本數是 2 個。
在這裏插入圖片描述
接下來是 jobmanager-service.yaml 的配置,jobmanager-service.yaml 的資源類型爲 Service,在 Service 中的配置相對少一些,spec 中配置需要暴露的服務端口的 port,在 selector 中,通過標籤選取 jobmanager 的 pod。

Job Cluster

除了 Session 模式,還有一種 Per Job 模式。在 Per Job 模式下,需要將用戶代碼都打到鏡像裏面,這樣如果業務邏輯的變動涉及到 Jar 包的修改,都需要重新生成鏡像,整個過程比較繁瑣,因此在生產環境中使用的比較少。

以使用公用 docker 倉庫爲例,Job Cluster 的運行步驟如下:

  • build 鏡像:在 flink/flink-container/docker 目錄下執行 build.sh 腳本,指定從哪個版本開始去構建鏡像,成功後會輸出 “Successfully tagged topspeed:latest” 的提示。

    sh build.sh --from-release --flink-version 1.7.0 --hadoop-version 2.8 --scala-version 2.11 --job-jar ~/flink/flink-1.7.1/examples/streaming/TopSpeedWindowing.jar --image-name topspeed
    
  • 上傳鏡像:在 hub.docker.com 上需要註冊賬號和創建倉庫進行上傳鏡像。

    docker tag topspeed zkb555/topspeedwindowing 
    docker push zkb555/topspeedwindowing
    
  • 啓動任務:在鏡像上傳之後,可以啓動任務。

    kubectl create -f job-cluster-service.yaml 
    FLINK_IMAGE_NAME=zkb555/topspeedwindowing:latest FLINK_JOB=org.apache.flink.streaming.examples.windowing.TopSpeedWindowing FLINK_JOB_PARALLELISM=3 envsubst < job-cluster-job.yaml.template | kubectl create -f – 
    FLINK_IMAGE_NAME=zkb555/topspeedwindowing:latest FLINK_JOB_PARALLELISM=4 envsubst < task-manager-deployment.yaml.template | kubectl create -f -
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章