Flink环境搭建与部署:从单机到云原生的实战路径

说实话,环境搭建这部分,很多初学者觉得就是装个软件、配个路径,没什么技术含量。但我做了这么多年大数据,见过太多因为环境问题排查好几天的情况。所以这一章,我会把几种主流部署模式掰开揉碎了讲,顺便分享一些我踩过的坑。

Flink的安装与配置:基础中的基础

先说说最基础的安装。Flink 依赖 Java 环境,JDK 版本建议 8 或 11。我个人习惯用 Oracle JDK 8,但 OpenJDK 11 也没问题。

核心步骤:

  1. 下载 Flink 二进制包(推荐从 Apache 官网或 CDH 镜像站)
  2. 解压到指定目录,比如 /opt/flink-1.17.0
  3. 配置 flink-conf.yaml 中的 jobmanager.rpc.address 和 taskmanager.numberOfTaskSlots
  4. 设置环境变量 FLINK_HOME 并加入 PATH

这里有个细节:taskmanager.numberOfTaskSlots 默认是 1,很多人忘了改。我刚开始用的时候,跑个简单的 WordCount 都卡,后来才发现是 slot 不够。你想想看,一个 TaskManager 只有一个 slot,并行度怎么提得上去?

我的习惯:生产环境一般把 slot 数设为 CPU 核心数,或者稍微少一点,留点资源给系统。比如 8 核机器,我设 6 个 slot。

Standalone模式部署:最纯粹的集群体验

Standalone 模式,说白了就是 Flink 自己管资源,不依赖 YARN 或 K8s。适合测试环境,或者小规模集群。

部署流程其实很简单:

  • 主节点启动 JobManager:bin/jobmanager.sh start
  • 从节点启动 TaskManager:bin/taskmanager.sh start
  • 通过 Web UI(默认 8081 端口)查看集群状态

但这里有个坑——高可用配置。Standalone 模式默认没有 HA,JobManager 挂了整个集群就废了。我曾经在一个演示环境里吃过这个亏,演示到一半 JobManager 进程被 OOM killer 干掉了,场面一度非常尴尬。

避坑指南:如果要用 Standalone 模式做生产,必须配置 ZooKeeper 做 HA。在 flink-conf.yaml 里加上:

high-availability: zookeeper
high-availability.zookeeper.quorum: host1:2181,host2:2181,host3:2181
high-availability.storageDir: hdfs:///flink/ha

YARN模式部署:大数据生态的标配

YARN 模式是我在生产中用得最多的。为什么?因为大部分公司的大数据集群都是 Hadoop 生态,YARN 作为资源管理器,天然适合跑 Flink 作业。

YARN 模式有两种提交方式:

模式 特点 适用场景
Session 模式 先启动一个常驻集群,再提交作业 多个小作业共享资源,适合开发测试
Per-Job 模式 每个作业单独启动一个集群,用完即销毁 生产环境,作业隔离性好

我个人强烈推荐 Per-Job 模式。为什么?因为 Session 模式下,一个作业出问题可能影响其他作业。我记得有一次,一个同事的 Session 集群里跑了个内存泄漏的作业,结果把整个集群搞崩了,所有人的任务都挂了。从那以后,我坚持用 Per-Job 模式。

提交命令也很简单:

./bin/flink run -m yarn-cluster \
  -yjm 1024 -ytm 2048 \
  -ys 2 -p 4 \
  ./examples/streaming/WordCount.jar

参数说明:-yjm 是 JobManager 内存,-ytm 是 TaskManager 内存,-ys 是每个 TaskManager 的 slot 数,-p 是并行度。

我的经验:YARN 模式下,记得配置 yarn.application-attempts 和 yarn.maximum-am-memory,否则作业可能因为资源不足被频繁杀掉。

Kubernetes模式部署:云原生的未来

Kubernetes 模式是 Flink 近两年主推的部署方式。说实话,刚开始接触 K8s 时我也觉得复杂,但用顺手之后,真香。

Flink on K8s 有两种部署方式:

  • Native Kubernetes:Flink 直接调用 K8s API 创建 Pod,资源管理更灵活
  • Standalone Kubernetes:手动定义 Deployment 和 Service,适合已有 K8s 运维经验的团队

我建议用 Native 模式。举个例子,提交一个作业到 K8s:

./bin/flink run -m kubernetes-cluster \
  -Dkubernetes.cluster-id=my-flink-cluster \
  -Dkubernetes.container.image=flink:1.17.0 \
  -Dkubernetes.jobmanager.cpu=1 \
  -Dkubernetes.taskmanager.cpu=2 \
  -Dtaskmanager.numberOfTaskSlots=4 \
  -p 8 \
  ./examples/streaming/WordCount.jar

这里要注意,镜像需要提前准备好。我一般用官方的 flink:1.17.0-scala_2.12,然后自己打个补丁包,把常用的 connector 和依赖加进去。

避坑指南:K8s 模式下,网络和存储是两大难点。我曾经因为没配置 hostNetwork 导致 TaskManager 之间通信超时。还有,Checkpoint 的存储路径一定要用 PersistentVolume,否则 Pod 重启后状态就丢了。

三种部署模式对比

为了让你更直观地选择,我整理了一张对比表:

维度 Standalone YARN Kubernetes
资源管理 手动分配 YARN 自动管理 K8s 自动管理
高可用 需额外配置 ZooKeeper 原生支持 原生支持
弹性伸缩 不支持 有限支持 完全支持
运维复杂度 低 中 高
适用场景 测试/小规模 生产环境(Hadoop 生态) 云原生/容器化

嗯,看到这里你应该明白了:没有最好的模式,只有最适合你的模式。如果公司已经有 Hadoop 集群,用 YARN 最省事;如果团队在推容器化,那就上 K8s;如果只是自己学习,Standalone 完全够用。

Flink部署模式知识体系

下面这张图是我自己画的,把三种部署模式的核心流程和关键点串起来了:

Flink 部署模式知识体系 Flink 部署模式 Standalone YARN Kubernetes JobManager + TaskManager Session / Per-Job Native / Standalone 选择建议:测试环境用 Standalone,Hadoop 生态用 YARN Per-Job,云原生用 K8s Native

这张图把三种模式的核心节点和选择建议都标出来了。你可以把它当作一个快速参考,以后选型时直接看这张图就行。

总结一下

环境搭建这部分,说白了就是三个选择:Standalone 简单但功能弱,YARN 稳定但依赖 Hadoop,K8s 灵活但学习成本高。我个人建议,如果你是初学者,先从 Standalone 入手,跑通一个 WordCount 再说。等理解了 Flink 的基本架构,再尝试 YARN 和 K8s。

嗯,这一章的内容就到这里。记住,环境搭建只是开始,真正的挑战在后面——作业调优、状态管理、Checkpoint 配置,这些才是决定你能否用好 Flink 的关键。