再聊 Flink 部署模式

536 阅读5分钟

一、部署模式

在一些应用场景中,对于集群资源分配和占用的方式,可能会有特定的需求。Flink为各种场景提供了不同的部署模式,主要有以下三种:

  • 会话模式(Session Mode)
  • 单作业模式(Per-Job Mode)
  • 应用模式(Application Mode)

它们的区别主要在于:集群的生命周期和资源分配方式不同、以及应用程序的 main()方法到底在哪里执行。客户端(Client)还是JobManager

1、会话模式(Session Mode)

会话模式需要先启动一个集群并保持一个会话,在这个会话中通过客户端提交作业。

集群启动时所有资源就都已经确定,所有提交的作业会竞争集群中的资源

适合于单个规模小、执行时间短的大量作业。

2、单作业模式(Per-Job Mode)

会话模式因为资源共享会导致很多问题,所以为了更好地隔离资源,我们可以考虑为每个提交的作业启动一个集群,这就是所谓的单作业(Per-Job)模式。

作业完成后,集群就会关闭,所有资源也会释放。

这些特性使得单作业模式在生产环境运行更加稳定,所以是实际应用的首选模式。

Flink本身无法直接这样运行,所以单作业模式一般需要借助一些资源管理框架来启动集群,比如YARN、Kubernetes(K8S)

Per-job mode 在Flink 1.15中已被弃用。请考虑在YARN上为每个作业启动专用集群的应用程序模式。

3、应用模式(Application Mode)

Session Mode 和 Per-Job Mode 模式下,应用代码都在客户端上执行,然后由客户端提交给JobManager。这种方式客户端需要占用大量网络带宽去下载依赖和把二进制数据发送给JobManager;加上很多情况下我们提交作业用的是同一个客户端,就会加重客户端所在节点的资源消耗。

所以解决办法就是,我们不要客户端了,直接把应用提交到JobManger上运行。而这也就代表着,我们需要为每一个提交的应用程序单独启动一个JobManager,也就是创建一个集群。这个JobManager只为执行这一个应用而存在,执行结束之后JobManager也就关闭了,这就是所谓的应用模式

Per-Job Mode 和 Application Mode 比较:

  • 相同点:都是提交作业之后才创建集群

  • 不同点:

    • 单作业模式是通过客户端来提交作业,解析出的每一个作业对应一个集群
    • 应用模式直接由JobManager执行应用程序(main方法)

二、 YARN 运行模式

YARN上部署的过程是:客户端把Flink应用提交给Yarn的ResourceManager,ResourceManager会向Yarn的NodeManager申请容器。在这些容器上,Flink会部署JobManager和TaskManager的实例,从而启动集群。Flink会根据运行在JobManger上的作业所需要的Slot数量动态分配TaskManager资源。

1、相关配置

在将Flink任务部署至YARN集群之前,需要确认集群是否安装有Hadoop,保证Hadoop版本至少在2.2以上,并且集群中安装有HDFS服务。

环境变量

sudo vim /etc/profile

HADOOP_HOME=/home/hadoop/opt/hadoop-3.3.5
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop
export HADOOP_CLASSPATH=`hadoop classpath`

启动Hadoop集群,包括HDFS和YARN

[hadoop@node01 hadoop-3.3.5]cd $HADOOP_HOME
[hadoop@node01 hadoop-3.3.5]start-dfs.sh
[hadoop@node01 hadoop-3.3.5]start-yarn.sh
2、会话模式部署

YARN的会话模式与独立集群略有不同,需要首先申请一个YARN会话(YARN Session)来启动Flink集群。具体步骤如下:

  1. 启动集群
# 启动Hadoop集群(HDFS、YARN)
[hadoop@node01 hadoop-3.3.5]start-dfs.sh
[hadoop@node01 hadoop-3.3.5]start-yarn.sh

#执行脚本命令向YARN集群申请资源,开启一个YARN会话,启动Flink集群
[hadoop@node01 flink-1.17.0]./bin/yarn-session.sh -d
3、单作业模式部署

在YARN环境中,由于有了外部平台做资源调度,所以我们也可以直接向YARN提交一个单独的作业,从而启动一个Flink集群。

命令行操作

# 提交作业
[hadoop@node01 flink-1.17.0]$ bin/flink run -d -t yarn-per-job -c com.vivace.wc.WordCountStream demo.jar
# 查看作业
[hadoop@node01 flink-1.17.0]$ bin/flink list -t yarn-per-job -Dyarn.application.id=application_XXXX_YY
# 取消作业
[hadoop@node01 flink-1.17.0]$ bin/flink cancel -t yarn-per-job -Dyarn.application.id=application_XXXX_YY <jobId>

这里的application_XXXX_YY是当前应用的ID,是作业的ID。注意如果取消作业,整个Flink集群也会停掉。

4、应用模式部署

应用模式与单作业模式类似,直接执行flink run-application命令即可。

命令行操作

[hadoop@node01 flink-1.17.0]$ bin/flink run-application -t yarn-application -c com.vivace.wc.WordCountStream  demo.jar 
[hadoop@node01 flink-1.17.0]$ bin/flink list -t yarn-application -Dyarn.application.id=application_XXXX_YY
[hadoop@node01 flink-1.17.0]$ bin/flink cancel -t yarn-application -Dyarn.application.id=application_XXXX_YY <jobId>

可以通过 yarn.provided.lib.dirs 配置选项指定位置,将flink的依赖上传到远程。

[hadoop@node01 flink-1.17.0]$ bin/flink run-application -t yarn-application -Dyarn.provided.lib.dirs="hdfs://node01:8020/flink-dist" -c com.vivace.wc.WordCountStream  hdfs://node01:8020/flink-jars/demo.jar

这种方式下flink本身的依赖和用户jar可以预先上传到HDFS,而不需要单独发送到集群,这就使得作业提交更加轻量了。

5、历史服务器

运行 Flink job 的集群一旦停止,只能去 yarn 或本地磁盘上查看日志,不再可以查看作业挂掉之前的运行的 Web UI,很难清楚知道作业在挂的那一刻到底发生了什么。如果我们还没有 Metrics 监控的话,那么完全就只能通过日志去分析和定位问题了,所以如果能还原之前的 Web UI,我们可以通过 UI 发现和定位一些问题。

Flink提供了历史服务器,用来在相应的 Flink 集群关闭后查询已完成作业的统计信息。我们都知道只有当作业处于运行中的状态,才能够查看到相关的WebUI统计信息。通过 History Server 我们才能查询这些已完成作业的统计信息,无论是正常退出还是异常退出。

此外,它对外提供了 REST API,它接受 HTTP 请求并使用 JSON 数据进行响应。Flink 任务停止后,JobManager 会将已经完成任务的统计信息进行存档,History Server 进程则在任务停止后可以对任务统计信息进行查询。比如:最后一次的 Checkpoint、任务运行时的相关配置。

创建存储目录

hadoop fs -mkdir -p /logs/flink-job

在 flink-config.yaml中添加如下配置

jobmanager.archive.fs.dir: hdfs://node01:8020/logs/flink-job
historyserver.web.address: node01
historyserver.web.port: 8082
historyserver.archive.fs.dir: hdfs://node01:8020/logs/flink-job
historyserver.archive.fs.refresh-interval: 5000

启动/停止历史服务器

bin/historyserver.sh start
bin/historyserver.sh stop