不同的应用场景,有时候对集群资源的分配和占用有不同的需求。所以Flink为各种场景提供了不同的部署模式。
根据集群的生命周期、资源的分配方式、main方法到底在哪里执行——客户端还是Client还是JobManager、资源管理 将Flink的部署模式分为四类:
会话模式
单作业模式
应用模式
会话模式首先要启动一个集群,这个集群的资源提前配置好。总共就一个集群,所有资源确定,所有作业/应用竞争这一个集群中的资源。所有job共享相同的JobManager和一定数量的TaskManager。
JobManager/TaskManager的生命周期不受job影响,在job提交之前集群预先将JobManager和TaskManager创建好,并且job执行结束之后不会被销毁。
在Client中生成JobGraph,然后提交给JobManager
优点:
缺点:
适合场景:
单个规模小、执行时间短的大量作业
会话模式由于多个作业运行在同一个集群,容易导致集群宕机,资源隔离性差。所以考虑为每个作业启动一个集群,这就是单作业模式。每个job都有单独的JobManager和TaskManager,随着job的提交而创建,job结束而销毁。
优点:
缺点:
资源浪费,重复创建和销毁JobManager和TaskManager
JobManager和TaskManager的生命周期全部交给CLusterManagement管理,管理复杂
Client生成JobGraph会消耗大量CPU,并且生成之后发送给JobManager消耗网络带宽,如果频繁提交任务,Client的压力会非常大。并且Client是顺序提交任务的,一旦某一个任务执行时间过长就会阻塞后面提交的任务
注:这个模式由于需要对各个job的资源是分开的,各个job的JobManager、TaskManager创建和销毁等管理和资源的分配是比会话模式要复杂的。所以Flink本身暂时不支持这种模式,需要结合外部的资源管理平台来完成。
1.11版本之后支持应用模式,Client将jar包等发送给JobManager,在JobManager中生成JobGraph,也就是说main方法在JobManager上执行而不是客户端上执行。以应用为单位(一个应用可能多个作业),一个应用创建一个集群。这里可以看成是创建仅在特定应用程序的Job之间共享的session集群。因为一个应用可能有多个job,而这多个job是在一个集群中的。Application 模式允许提交由多个Job组成的应用程序。Job执行的顺序不受部署模式的影响,但受启动Job的调用的影响。使用阻塞的
execute()
方法,将是一个顺序执行的效果,结果就是"下一个"Job的执行被推迟到“该”Job完成为止。相反,一旦提交当前作业,非阻塞executeAsync()
方法将立即继续提交“下一个”Job。
优点:
缺点:
这里我们所讲到的部署模式,相对是比较抽象的概念。实际应用时,一般需要和资源管理平台结合起来,选择特定的模式来分配资源、部署应用。
默认只启动jobmanager,之后根据job任务提交情况,动态的申请、启动taskmanager计算资源。这个资源的动态分配,也就是资源管理是交由第三方资源管理器如Yarn、K8s等
Flink自己可以进行资源管理,但是没有那么灵活、好用。同时也可以结合第三方的资源管理器进行资源管理,flink专注业务逻辑的实现而资源的管理交由第三方资源管理器。
独立模式是独立运行的,不依赖任何外部的资源管理平台;当然独立也是有代价的:如果资源不足,或者出现故障,没有自动扩展或重分配资源的保证,必须手动处理。所以独立模式一般只用在开发测试或作业非常少的场景下。
1)先启动一个集群
./start-cluster.sh
2)通过Client提交作业(参考第二章)
方式一:通过Web UI提交
方式二:通过命令
flink run -m hadoop102:8081 -c com.zlin.wc.StreamWordCount ./chapter2-1.0-SNAPSHOT.jar
Flink的Standalone集群并不支持单作业模式部署。因为单作业模式需要借助一些资源管理平台。
应用模式下不会提前创建集群,所以不能调用start-cluster.sh脚本。我们可以使用同样在bin目录下的standalone-job.sh来创建一个JobManager
具体步骤如下:
(1)将jar包放到lib/目录下
[root@hadoop102 lib]# cp /opt/jars/chapter2-1.0-SNAPSHOT.jar /opt/module/flink-1.17.1/lib
(2)启动JobManager
[root@hadoop102 bin]# /opt/module/flink-1.17.1/bin/standalone-job.sh start --job-classname com.zlin.wc.StreamWordCount
这里不用再指定jar包,因为脚本会到lib/目录下扫描
我们可以看到,虽然提交了作业,但是申请不到资源,一直处于CREATED状态。需要启动TaskManager。
(3)启动TaskManager
[root@hadoop102 bin]# /opt/module/flink-1.17.1/bin/taskmanager.sh start
(4) 如果希望停掉集群,可以使用
/opt/module/flink-1.16.0/bin/standalone-job.sh stop
/opt/module/flink-1.16.0/bin/taskmanager.sh stop
Native模式是对Session和Per-Job的优化,把生成多少TaskManager交给资源调度器。支持的资源调度器有Yarn,Mesos,Kubernetes等。
前期准备
需要安装hadoop(Yarn、HDFS)
配置环境变量
[root@hadoop102 ~]# vim ~/.bashrc
#SET HADOOP_HOME
export HADOOP_HOME=/opt/module/hadoop-2.7.7
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop
export HADOOP_CLASSPATH=`hadoop classpath`
启动hadoop(Yarn、HDFS服务)
[root@hadoop102 sbin]# /opt/module/hadoop-2.7.7/sbin/start-all.sh
1)启动集群
第一步:首先要启动hadoop相关服务(yarn、hdfs)
第二步:执行脚本命令向YARN集群申请资源,开启一个YARN会话,启动Flink集群
bin/yarn-session.sh -nm test -d
在YARN的ResourceManager界面查看执行情况
Yarn WEB UI: http://hadoop102:8088/
可用参数:
-d:分离模式,即yarn session后台运行
-jm:JobManager内存,默认单位MB
-nm:任务名
-qu:指定Yarn队列名
-tm:每个TaskManager的内存
2)提交作业
两种提交方式:
Web UI提交(略)
命令行提交
[root@hadoop102 bin]# flink run -c com.zlin.wc.StreamWordCount /opt/jars/chapter2-1.0-SNAPSHOT.jar
从Yarn Web UI -> 点击对应提交的任务的application ID -> 点击Tracking URL:ApplicationMaster -> 进入到Flink web ui 可查看到提交的任务
尝试1:可以再提交一个任务吗?
可以,而且由yarn自己去动态分配,且提交到同一个application中
尝试2:再创建一个Yarn session?
2023-06-18 18:36:55,836 INFO org.apache.flink.yarn.YarnClusterDescriptor [] - Deployment took more than 60 seconds. Please check if the requested resources are available in the YARN cluster
会卡住,无法创建成功,不知道是不是资源问题还是说会话模式本来就只有一个集群不让创建。
[root@hadoop102 bin]# flink run -t yarn-per-job -c com.zlin.wc.StreamWordCount /opt/jars/chapter2-1.0-SNAPSHOT.jar
查看或者取消作业:
[atguigu@hadoop102 flink-1.17.0]$ bin/flink list -t yarn-per-job -Dyarn.application.id=application_XXXX_YY
[atguigu@hadoop102 flink-1.17.0]$ bin/flink cancel -t yarn-per-job -Dyarn.application.id=application_XXXX_YY <jobId>
这里的application_XXXX_YY是当前应用的ID,是作业的ID。注意如果取消作业,整个Flink集群也会停掉。
命令行提交
1)提交
[root@hadoop102 bin]# flink run-application -t yarn-application -c com.zlin.wc.StreamWordCount /opt/jars/chapter2-1.0-SNAPSHOT.jar
2)查看和取消作业
flink list -t yarn-application -Dyarn.application.id=application_XXXX_YY
flink cancel -t yarn-application -Dyarn.application.id=application_XXXX_YY <jobId>
上传HDFS提交
1)上传jar包到hdfs
我们知道在客户端生成JobGraph一旦提交任务数过多,会造成很大压力,而应用模式部署在JM上生成JobGraph所以可以解决这个问题。但是我们提交时还是需要经过网络传输将jar包传送到JM,提交速度会受到影响。我们可以将jar包提前上传到hdfs。
可以通过yarn.provided.lib.dirs配置选项指定位置,将jar上传到hdfs。这种方式下 jar 可以预先上传到 HDFS,而不需要单独发送到集群,这就使得作业提交更加轻量了。
[root@hadoop102 flink-1.17.1]# hadoop fs -mkdir /flink-jars
[root@hadoop102 flink-1.17.1]# hadoop fs -put /opt/jars/chapter2-1.0-SNAPSHOT.jar /flink-jars
2)上传flink的lib和plugins到HDFS上
[root@hadoop102 flink-1.17.1]# hadoop fs -mkdir /flink-dist
[root@hadoop102 flink-1.17.1]# hadoop fs -put lib/ /flink-dist
[root@hadoop102 flink-1.17.1]# hadoop fs -put plugins/ /flink-dist
2)提交作业
[root@hadoop102 flink-1.17.1]# bin/flink run-application -t yarn-application -Dyarn.provided.lib.dirs="hdfs://hadoop102:8020/flink-dist" -c com.zlin.wc.StreamWordCount hdfs://hadoop102:8020/flink-jars/chapter2-1.0-SNAPSHOT.jar
容器化部署是如今业界流行的一项技术,基于Docker镜像运行能够让用户更加方便地对应用进行管理和运维。容器管理工具中最为流行的就是Kubernetes(k8s),而Flink也在最近的版本中支持了k8s部署模式。后续补充。。。
附:Flink可以结合常见的资源管理器,各种资源调度器中支持的运行模式如下图:
运行 Flink job 的集群一旦停止,只能去 yarn 或本地磁盘上查看日志,不再可以查看作业挂掉之前的运行的 Web UI,很难清楚知道作业在挂的那一刻到底发生了什么。如果我们还没有 Metrics 监控的话,那么完全就只能通过日志去分析和定位问题了,所以如果能还原之前的 Web UI,我们可以通过 UI 发现和定位一些问题。
Flink提供了历史服务器,用来在相应的 Flink 集群关闭后查询已完成作业的统计信息。我们都知道只有当作业处于运行中的状态,才能够查看到相关的WebUI统计信息。通过 History Server 我们才能查询这些已完成作业的统计信息,无论是正常退出还是异常退出。
此外,它对外提供了 REST API,它接受 HTTP 请求并使用 JSON 数据进行响应。Flink 任务停止后,JobManager 会将已经完成任务的统计信息进行存档,History Server 进程则在任务停止后可以对任务统计信息进行查询。比如:最后一次的 Checkpoint、任务运行时的相关配置。
配置历史服务器:
1)创建存储目录
hadoop fs -mkdir -p /logs/flink-job
2)在flink配置问价flink-conf.yaml进行配置
jobmanager.archive.fs.dir: hdfs://hadoop102:9000/logs/flink-job
historyserver.web.address: hadoop102
historyserver.web.port: 8082
historyserver.archive.fs.dir: hdfs://hadoop102:9000/logs/flink-job
historyserver.archive.fs.refresh-interval: 5000
注意:这里hdfs://hadoop102:9000/logs/flink-job的端口需要根据hadoop版本来定。hadoop1.x是8020,hadoop2.x是9000
3)启动历史服务器
[root@hadoop102 bin]# ./historyserver.sh start
Starting historyserver daemon on host hadoop102.
# 启动成功会有一个HistoryServer的进程
HistoryServer
4)停止历史服务器
[root@hadoop102 bin]# ./historyserver.sh stop
5)在浏览器地址栏输入:**[http://hadoop102:8082]**查看已经停止的job的统计信息