3. Flink on YARN实战:环境准备、提交命令、资源参数配置、日志查看与问题排查
好,咱们直接进入正题。Flink on YARN 是生产环境里最常见的部署方式之一。说白了,就是把 Flink 作业交给 YARN 去管理资源和调度。你想想看,YARN 本来就是做资源管理的,Flink 作业跑在上面,资源分配、容错、日志这些事都能交给 YARN 来处理,省心不少。
我个人习惯把这一整套流程分成四个环节:环境准备、提交命令、参数调优、问题排查。咱们一个一个来过。
核心思路: Flink on YARN 的本质是让 YARN 的 ApplicationMaster 来启动 Flink 的 JobManager 和 TaskManager。你提交的 jar 包和配置,决定了作业怎么跑、跑在哪、用多少资源。
3.1 环境准备:先把地基打好
环境准备这块,我踩过不少坑。有一次在客户现场,折腾了半天发现是 Hadoop 版本和 Flink 不兼容。所以,咱们先把基础环境理清楚。
你需要准备的东西:
- Hadoop 集群:YARN 必须跑起来,ResourceManager 和 NodeManager 都正常。建议 Hadoop 2.7+ 或 3.x。
- Flink 发行包:去官网下载对应 Hadoop 版本的包。比如
flink-1.17.0-bin-scala_2.12.tgz。 - Java 环境:JDK 8 或 11,这个不用多说。
- 环境变量:
HADOOP_HOME、HADOOP_CONF_DIR必须配好。Flink 会通过它们找到 YARN 的配置。
我的小习惯: 在 flink-conf.yaml 里显式设置 yarn.application.name,这样在 YARN 界面上能一眼认出你的作业。不然全是 "Flink session",找起来头疼。
验证环境很简单,跑一行命令:
echo $HADOOP_HOME
echo $HADOOP_CONF_DIR
hadoop version
如果都能正常输出,环境就差不多了。
3.2 提交命令:两种模式,两种玩法
Flink on YARN 有两种提交模式:Session 模式 和 Per-Job 模式。我刚开始用的时候也纠结过选哪个,后来发现其实看场景。
| 模式 | 特点 | 适用场景 |
|---|---|---|
| Session 模式 | 先启动一个常驻集群,再往里面提交作业。资源复用,启动快。 | 多个小作业、交互式查询、开发测试。 |
| Per-Job 模式 | 每个作业单独启动一个 YARN 集群,作业结束集群自动释放。 | 生产环境的大作业、需要隔离资源的场景。 |
Session 模式提交示例:
# 先启动一个 YARN Session
./bin/yarn-session.sh -n 4 -s 2 -jm 1024 -tm 2048
# 然后提交作业到该 Session
./bin/flink run -m yarn-cluster -yn 4 ./examples/streaming/WordCount.jar
Per-Job 模式提交示例:
./bin/flink run -m yarn-cluster \
-yn 4 \
-yjm 1024 \
-ytm 2048 \
-ys 2 \
-yqu default \
./examples/streaming/WordCount.jar
注意: Per-Job 模式在 Flink 1.15 之后被标记为废弃,推荐使用 Application 模式。但很多老项目还在用,所以我还是讲一下。新项目建议直接用 Application 模式。
3.3 资源参数配置:别让作业饿死或撑死
资源参数配置是门学问。配少了作业跑不动,配多了集群资源浪费。我曾经遇到过一个作业,TaskManager 内存配了 8G,结果数据量只有几百兆,白白浪费资源。
核心参数一览:
| 参数 | 说明 | 建议值 |
|---|---|---|
-yn / yarn.containers |
TaskManager 数量 | 根据并行度来,一般 4-16 个 |
-yjm / yarn.jobmanager.memory |
JobManager 内存 (MB) | 1024-4096,看作业复杂度 |
-ytm / yarn.taskmanager.memory |
每个 TaskManager 内存 (MB) | 2048-8192,看数据量 |
-ys / yarn.slots |
每个 TaskManager 的 Slot 数 | 一般 2-4,和 CPU 核数对应 |
-yqu / yarn.queue |
YARN 队列 | 根据集群配置,比如 root.production |
我的经验公式:
- 每个 Slot 分配 1-2 GB 内存,看算子复杂度。
- TaskManager 内存 = Slot 数 × 每个 Slot 内存 + 管理开销(约 10%)。
- 并行度不要超过集群总 Slot 数,否则作业会排队等资源。
避坑指南: 我曾经把 yarn.taskmanager.memory 设得比 YARN 的 yarn.nodemanager.resource.memory-mb 还大,结果作业一直提交失败。后来才发现是资源超限了。记住,TaskManager 内存不能超过 NodeManager 的可用内存。
3.4 日志查看与问题排查:遇到问题别慌
作业跑起来之后,日志就是你的眼睛。Flink on YARN 的日志分布在好几个地方,我刚开始找日志找得头大。
日志位置一览:
- YARN 界面:通过 ResourceManager 的 Web UI(默认 8088 端口)找到你的 Application,点击 "Logs" 可以查看 AM 和 Container 的日志。
- Flink Web UI:JobManager 的 Web 界面(默认 8081 端口),可以看到作业的实时状态、TaskManager 列表、异常信息。
- 本地日志:如果你用 Session 模式,Flink 客户端会输出日志到
log/目录下。
常见问题排查思路:
- 作业提交失败:先看 YARN 界面,Application 状态是 FAILED 还是 KILLED。FAILED 一般是资源不足或配置错误,KILLED 可能是内存超限或被管理员杀掉。
- 作业运行缓慢:去 Flink Web UI 看背压(Back Pressure)和 Checkpoint 耗时。背压高说明下游处理不过来,Checkpoint 超时说明状态后端有问题。
- TaskManager 丢失:检查 YARN 日志,看是不是 NodeManager 把 Container 杀了。通常是内存超限,调大
yarn.taskmanager.memory或者减小并行度。
我的排查习惯: 遇到问题先看 YARN 的 Application 日志,里面会打印出 Flink 的异常堆栈。如果堆栈信息不全,再去 Flink Web UI 看 TaskManager 的 stdout 和 stderr。这两个地方基本能覆盖 90% 的问题。
一个实用的命令:
# 查看 YARN 日志(需要知道 Application ID)
yarn logs -applicationId application_123456789_0001
这个命令会把所有 Container 的日志拉下来,方便本地分析。我经常用它来排查那些在界面上看不清楚的异常。
注意: YARN 日志默认只保留一段时间,如果作业已经结束很久,日志可能已经被清理了。建议在作业运行时就开启日志持久化,或者把关键日志输出到外部系统(比如 Kafka、Elasticsearch)。