1. 零基础也能懂Flink Standalone 模式到底是什么如果你刚接触大数据听到“实时计算”、“流处理”这些词可能有点发怵觉得这是大厂工程师才玩得转的东西。别担心今天咱们就来聊一个特别适合新手入门的起点——Flink Standalone 模式。你可以把它想象成一个“乐高基础套装”。你想玩乐高但一开始没必要去买那个几千块零件、带电动马达的复杂套装。Standalone 模式就是那个最基础、零件不多、但能让你快速拼出一个小房子或小汽车的套装。它包含了 Flink 最核心的玩法让你能先跑起来感受乐趣建立信心。那么这个“基础套装”具体是啥呢简单说Flink Standalone 模式就是 Flink 自带的一种独立集群运行方式。这里的“独立”是关键它意味着你不需要额外安装和配置像 Hadoop YARN 或者 Kubernetes 这类复杂的“资源大管家”。Flink 自己就能管理它所需要的计算资源比如内存、CPU自己当自己的老板。这带来的最大好处就是部署极其简单没有那么多外部依赖特别适合我们个人在电脑上学习或者在几台服务器上搭建一个小型测试环境快速验证你的实时处理想法。在这个“小作坊”里有两个核心角色你一定要记住JobManager老大和TaskManager小弟。想象一下你接了一个做手工订单的活儿。JobManager 就是那个负责接单、看图纸、把任务拆成一个个小步骤比如先裁剪、再缝合、最后包装并指挥小弟们去干的“工头”。而 TaskManager 就是那些真正动手干活儿的小弟他们每人手里都有一些工具计算资源工头分配什么步骤他们就执行什么。一个 Flink Standalone 集群里通常有一个 JobManager当然也可以配置高可用有备用的老大和若干个 TaskManager。你写的 Flink 实时处理程序Job就是由 JobManager 接收、拆解然后分发到各个 TaskManager 上去并行执行的。我刚开始学的时候也纠结过为啥不用更“高级”的 YARN 模式。后来想明白了学习新技术就像学开车你得先在自己的小场地里把方向盘、刹车、油门摸熟了再上路应对复杂交通。Standalone 模式就是这个“小场地”让你能专注于理解 Flink 程序怎么写、数据怎么流、任务怎么跑而不被外围复杂的集群管理问题干扰。等你在这里玩熟了再迁移到 YARN 或 K8s 上你会发现核心概念完全一样只是“办公场地”换了个更气派、能容纳更多人的大楼而已。2. 动手前的准备给你的电脑“热身”好了理论懂了手痒想实操了是吧别急磨刀不误砍柴工咱们先把准备工作做好。这部分其实很简单就是检查一下你的“工作台”是否达标把需要的“工具”下载好。我以最常用的 Linux 环境比如 CentOS 或 Ubuntu为例如果你用 Mac命令也基本通用Windows 用户建议使用 WSL2体验会好很多。第一样也是最重要的Java 环境。Flink 是个 Java 系的框架所以必须要有 Java 运行环境。推荐使用Java 8或者Java 11这两个是经过广泛验证与 Flink 兼容性最好的版本。别用太新的 Java 17 或更高版本可能会遇到一些兼容性问题咱们新手求稳为主。怎么检查有没有装 Java 呢打开你的终端命令行输入java -version如果蹦出来类似“openjdk version “1.8.0_301””这样的信息恭喜你这一步过了。如果提示“command not found”那就需要安装一下。安装过程网上教程非常多核心就是下载 JDK 压缩包解压然后配置一个叫JAVA_HOME的环境变量。这里我给你个最直白的配置方法编辑/etc/profile文件需要 root 权限可以用sudo vim /etc/profileexport JAVA_HOME/opt/jdk1.8.0_301 # 这里路径要换成你实际解压 JDK 的目录 export PATH$JAVA_HOME/bin:$PATH保存退出后执行source /etc/profile让配置立刻生效然后再用java -version验证一下。第二样Flink 安装包。去 Flink 的官网Apache 开源项目直接搜就能找到下载页面找一个稳定版的“二进制包”。对于新手我强烈建议下载名字里带“bin”和“scala_2.12”的比如flink-1.17.0-bin-scala_2.12.tgz。这个包已经包含了运行所需的所有核心库开箱即用。版本号不用追求最新1.17.x 或 1.18.x 都是非常稳定且资料丰富的选择。第三样网络畅通。如果你是在单台电脑上玩这步可以忽略。但如果你想在多台机器比如三台云服务器上搭建集群那么一定要确保机器之间网络能互通并且防火墙不能阻挡关键端口。Flink 的 JobManager 和 TaskManager 之间需要通过网络通信来协调工作。一个简单的检查方法是在作为 JobManager 的机器上尝试用ping命令去连其他机器的 hostname 或 IP 地址要能通。对于防火墙最省事的做法仅限学习测试环境是先暂时关闭。在 CentOS 7/8 上可以执行sudo systemctl stop firewalld sudo systemctl disable firewalld在 Ubuntu 上可能是sudo ufw disable。关防火墙只是为了排除干扰等集群跑通了你可以再研究如何精确地开放所需端口比如 8081 Web UI 端口6123 RPC 端口等。3. 5分钟极速搭建Standalone 集群安装与配置准备工作搞定现在进入最核心的安装部署环节。我保证跟着我的步骤走5分钟真的能让你的集群跑起来。为了更贴近实际我们假设一个简单的三节点集群场景一台机器当“老大”JobManager三台机器都当“小弟”TaskManager。如果你的资源有限完全可以用一台机器扮演所有角色配置方法是一样的。3.1 第一步解压与目录准备假设我们把 Flink 安装包上传到了bigdata01这台机器的/opt/software/目录下。我们执行解压并把它放到一个固定的安装路径# 进入软件包目录 cd /opt/software/ # 解压到 /opt/apps/ 目录下 tar -zxvf flink-1.17.0-bin-scala_2.12.tgz -C /opt/apps/ # 进入安装目录为了方便可以改个短名字 cd /opt/apps/ mv flink-1.17.0 flink现在/opt/apps/flink就是我们的 Flink 主目录了。里面bin/是启动脚本conf/是配置文件lib/是依赖库examples/是官方示例结构非常清晰。3.2 第二步关键配置文件修改所有集群的奥秘几乎都藏在conf/目录下的几个文件里。我们逐一击破。首先配置flink-conf.yaml。这是 Flink 的主配置文件参数很多但我们新手只需关注几个核心的cd /opt/apps/flink/conf vim flink-conf.yaml找到并修改或添加以下配置#后面是我的注释实际文件里可以不加# 指定 JobManager老大的 RPC 地址这里就是 bigdata01 这台机器 jobmanager.rpc.address: bigdata01 # 绑定地址0.0.0.0 表示监听所有网络接口 jobmanager.bind-host: 0.0.0.0 # Web UI 的访问地址和绑定地址 rest.address: bigdata01 rest.bind-address: 0.0.0.0 # 指定 TaskManager小弟的绑定地址和主机名 # 注意这个 taskmanager.host 在每台机器上应该设置成自己的主机名 taskmanager.bind-host: 0.0.0.0 taskmanager.host: bigdata01 # 在 bigdata01 上先这么写分发到其他机器后要改 # 可选但推荐调整内存和并行度资源避免默认值太小 # JobManager 的总进程内存学习环境 1G 够用了 jobmanager.memory.process.size: 1024m # 每个 TaskManager 的总进程内存也先给 1G taskmanager.memory.process.size: 1024m # 每个 TaskManager 有几个“任务槽”Slot可以理解为有几个干活的手。 # 通常设置为这台机器的 CPU 核心数。假设我们机器是2核就设为2。 taskmanager.numberOfTaskSlots: 2 # 任务的默认并行度如果不指定任务就会用这个值。我们先设为2。 parallelism.default: 2接着配置workers文件。这个文件告诉 Flink哪些机器是干活的 TaskManager。编辑它vim workers内容就是所有 TaskManager 节点的主机名每行一个。在我们的三节点规划里三台机器都干活bigdata01 bigdata02 bigdata03然后配置masters文件。这个文件指定 JobManager 的位置和它的 Web UI 端口vim masters内容如下8081是默认Web端口bigdata01:80813.3 第三步分发与节点个性化配置因为我们是在bigdata01上修改的配置现在需要把整个flink目录复制到另外两台机器上。你可以用scp命令手动拷贝也可以用像rsync这样的工具。假设我们有个简单的同步脚本xsync.sh或者直接用 scp# 使用 scp 递归拷贝目录到 bigdata02 和 bigdata03 scp -r /opt/apps/flink bigdata02:/opt/apps/ scp -r /opt/apps/flink bigdata03:/opt/apps/重要的一步拷贝过去后bigdata02和bigdata03机器上的flink-conf.yaml文件里taskmanager.host这个配置还是bigdata01这不对。每台 TaskManager 需要知道自己的主机名。所以你需要分别登录到这两台机器上修改在bigdata02上vim /opt/apps/flink/conf/flink-conf.yaml # 将 taskmanager.host 改为 bigdata02 taskmanager.host: bigdata02在bigdata03上vim /opt/apps/flink/conf/flink-conf.yaml # 将 taskmanager.host 改为 bigdata03 taskmanager.host: bigdata03最后配置环境变量可选但方便。在每台机器的/etc/profile文件末尾添加export FLINK_HOME/opt/apps/flink export PATH$PATH:$FLINK_HOME/bin然后执行source /etc/profile生效。这样以后在任何位置都能直接运行flink命令了。3.4 第四步启动集群与验证激动人心的时刻到了回到bigdata01我们的 JobManager 节点进入 Flink 的 bin 目录执行启动脚本cd /opt/apps/flink/bin ./start-cluster.sh这个脚本会读取我们刚才配置的masters和workers文件依次去启动 JobManager 和所有 TaskManager。如果一切顺利你会看到一些启动日志。现在我们来检查一下进程是否都起来了。在bigdata01上执行jps你应该能看到一个StandaloneSessionClusterEntrypoint进程这就是 JobManager和一个TaskManagerRunner进程。 在bigdata02和bigdata03上执行jps你应该只能看到TaskManagerRunner进程。更直观的方法是打开浏览器访问http://bigdata01:8081。你应该能看到 Flink 华丽的 Web UI 界面。在首页的 “Task Managers” 标签页下你应该能看到3个 TaskManager每个的 “Slots” 数是你配置的2总共就有6个可用的任务槽。这就说明你的 Standalone 集群已经成功搭建并运行起来了4. 实战演练跑通你的第一个实时 WordCount集群跑起来了不跑个程序总觉得缺点什么。咱们不玩虚的就用 Flink 自带的经典例子——流处理的 WordCount。别小看它这个例子涵盖了从数据源读取、转换、分组聚合到结果输出的完整流程是理解 Flink 流处理思想的绝佳起点。4.1 提交官方示例任务Flink 安装包里贴心地为我们准备了很多示例 Jar 包。我们找一个流处理的 WordCount 来跑。通常它在examples/streaming目录下。在bigdata01上执行以下命令提交任务cd /opt/apps/flink ./bin/flink run ./examples/streaming/WordCount.jar这条命令会向我们的 Standalone 集群提交一个 Job。你会看到控制台输出一大堆日志最后显示任务提交成功并给出了 Job ID。现在立刻刷新你的 Web UI (http://bigdata01:8081)在 “Running Jobs” 或 “Completed Jobs” 里找到这个任务。点进去你可以看到这个任务的执行流程图Dataflow Graph非常直观地展示了数据从 Source源到 Map转换再到 Keyed Aggregation聚合的整个过程。这个默认的示例程序其数据源是内置的一段英文文本。它会在集群中运行完成单词计数后将结果打印到每个 TaskManager 的标准输出stdout上。要看到结果你需要去查看 TaskManager 的日志文件。日志文件通常在log目录下名字类似flink-user-taskexecutor-hostname.out。你可以用tail -f命令来实时查看。不过对于新手更简单的方法是这个示例主要是为了验证集群能正常工作看到任务成功提交并运行我们的目的就达到了。4.2 进阶处理你自己的数据文件用内置数据不过瘾我们来玩点真的处理一个你自己准备的文本文件。首先在bigdata01上创建一个简单的文本文件比如/home/wc.txt里面随便写几行英文句子。然后使用 WordCount 示例程序来处理这个文件。这个 Jar 包支持传入--input和--output参数来指定输入输出路径./bin/flink run ./examples/streaming/WordCount.jar \ --input /home/wc.txt \ --output /home/result注意这里有一个新手必踩的“坑”当你满怀期待地执行这条命令时很可能会失败报错信息里提到 “SimpleStreamFormat is not splittable” 或者文件找不到。这是为什么呢因为我们的集群有三个 TaskManager它们可能分布在不同的机器上。当你指定--input /home/wc.txt时Flink 默认会尝试在每个 TaskManager 所在的机器上寻找这个路径的文件。但是你的wc.txt只存在于bigdata01的/home目录下bigdata02和bigdata03上没有这个文件所以任务就会失败。解决办法有两种使用共享存储把文件放在一个所有节点都能访问的地方比如 NFS 共享目录或者 HDFS 上。这是生产环境的常规做法。分发文件到所有节点对于学习测试最简单粗暴的方法就是把文件拷贝到所有 TaskManager 机器的相同路径下。用我们之前提到的scp命令就行scp /home/wc.txt bigdata02:/home/ scp /home/wc.txt bigdata03:/home/文件分发完毕后再次提交任务应该就能成功运行了。任务结束后结果会写入--output指定的路径同样地这个路径也需要在所有节点存在或者是一个共享路径。结果文件可能生成在任意一个 TaskManager 节点上你需要去各个节点的/home目录下找找看那个result文件。通过这个小小的“踩坑”你其实学到了分布式系统的一个重要概念数据本地性和共享存储。在真正的生产环境中数据通常都存放在 HDFS、S3 这类分布式文件系统上所有计算节点都能访问从而避免了我们刚才遇到的问题。5. 避坑指南与核心原理浅析走完了安装和实战你可能觉得还挺顺利。但我在刚开始玩的时候可没少遇到问题。下面我把几个常见的“坑”和解决方法列出来你遇到时可以直接来查。坑一启动集群时报 “No Java executable found” 或类似错误。原因Java 环境没装好或者JAVA_HOME环境变量没配置正确或者配置了但没生效。解决首先用which java和java -version确认 Java 命令可用。然后检查 Flink 的conf/flink-conf.yaml里有没有设置env.java.home这个参数你可以显式地把它指向你的 JDK 目录例如env.java.home: /opt/jdk1.8.0_301。这比依赖系统环境变量更可靠。坑二Web UI (8081端口) 打不开。原因1防火墙没关端口被阻断。解决确认防火墙已关闭或者已开放 8081 端口。原因2flink-conf.yaml中的rest.address配置成了localhost或127.0.0.1。解决确保rest.address配置成了服务器对外的 IP 地址或主机名如bigdata01并且rest.bind-address是0.0.0.0。原因3端口被其他程序占用。解决用netstat -tlnp | grep 8081查看端口占用情况杀掉占用进程或者修改flink-conf.yaml中的rest.port为其他端口。坑三TaskManager 启动失败在 Web UI 里看不到或者显示为丢失。原因1workers文件里的主机名配置错误或者主机名无法解析ping 不通。解决确保每台机器的主机名配置正确/etc/hosts文件并且机器之间可以通过主机名互相 ping 通。对于单机伪集群workers里可以写localhost。原因2每台 TaskManager 机器上的flink-conf.yaml中taskmanager.host没有改成自己的主机名。解决如我们之前步骤强调的一定要逐台修改这个配置。原因3内存配置不足。解决如果机器资源紧张可以尝试在flink-conf.yaml中调小taskmanager.memory.process.size和jobmanager.memory.process.size的值比如设为512m试试。坑四提交任务后一直卡在 “Scheduling” 状态或者报 “No resource available” 错误。原因没有足够的 Task Slot 来运行任务。你任务所需的并行度大于集群当前可用的 Slot 总数。解决检查 Web UI 首页的 “Total Task Slots”。如果你有3个 TaskManager每个配置了taskmanager.numberOfTaskSlots: 1那么总共有3个 Slot。如果你提交任务时或代码默认并行度设置的并行度是4那就会有一个子任务没地方跑。解决办法是增加 TaskManager 数量或者增加每个 TaskManager 的 Slot 数或者降低任务的并行度。聊完了坑我们再简单扯两句原理让你知其然也知其所以然。当你执行start-cluster.sh时脚本会先去masters文件里找到 JobManager 的地址启动一个 JVM 进程这就是集群的“大脑”。然后它根据workers文件列表通过 SSH 连接到每台机器启动 TaskManager 进程。JobManager 和 TaskManager 之间通过 RPC远程过程调用保持心跳和通信。你提交的 Jar 包首先被传到 JobManagerJobManager 解析出其中的“作业图”JobGraph然后根据可用的 Task Slot将图里的各个算子比如 Map、Reduce分配到具体的 TaskManager 上去执行。TaskManager 启动后会向 JobManager 注册自己并汇报自己有多少个空闲的 Slot。整个调度过程都在 JobManager 的统筹下完成。理解了这套简单的协作机制你再去学习更复杂的 YARN 模式就会发现它只是把“启动 TaskManager”这个工作交给了 YARN 这个资源管理器来做核心的 JobManager 和 TaskManager 的角色一点没变。6. 深入一步Web UI 与历史服务器集群跑起来任务也能提交了我们还得学会“看”。Flink 提供了非常强大的 Web UI是我们监控和调试任务的“眼睛”。默认的http://bigdata01:8081这个界面我们叫它Flink Web Dashboard。在这里你可以看到集群概览总 Task Slot 数可用数运行的 Job 数。作业管理提交、取消、暂停作业查看所有运行中和已完成的作业列表。作业详情点击一个 Job能看到它的执行计划图可视化展示数据流、各个算子的状态、吞吐量、背压Backpressure情况、指标Metrics等。这对于分析任务瓶颈至关重要。TaskManager 列表查看每个 TaskManager 的状态、资源使用情况、日志等。但是你有没有发现一个问题一旦你重启了 Flink 集群之前在这个 Web UI 上跑过的任务记录就全没了。这对于回顾历史任务、分析问题很不方便。这就需要请出另一个组件History Server历史服务器。历史服务器的作用就是像一个“档案馆”把已经运行完成的 Job 的元数据比如执行计划、配置、指标摘要等持久化保存下来通常是存到 HDFS 或本地文件系统然后通过另一个 Web 端口默认 8082提供查询界面。这样即使集群重启你也能在历史服务器上查到之前所有任务的记录。配置历史服务器稍微麻烦一点因为它需要依赖一个分布式文件系统如 HDFS来存储数据并且需要额外的 Hadoop 依赖包。对于纯新手我建议可以先不配置专注于核心的 Standalone 集群和任务开发。等你对 Flink 比较熟悉并且环境里有 HDFS 时再去研究它。简单来说步骤是1. 将 Hadoop 的客户端 Jar 包放入 Flink 的lib/目录。2. 在flink-conf.yaml中配置历史服务器的地址、端口以及归档目录指向 HDFS 路径。3. 使用bin/historyserver.sh start启动它。这样你就能通过http://bigdata01:8082访问一个独立的历史任务查询界面了。7. 从 Standalone 出发你的下一步是什么恭喜你如果你跟着文章一步步操作下来现在已经拥有了一个完全在自己掌控之中的 Flink 实时计算集群并且成功运行了第一个流处理任务。这已经超越了绝大多数还在概念阶段徘徊的学习者。Standalone 模式就像你亲手搭建的第一个机器人模型虽然简单但齿轮如何咬合、电机如何驱动你都看得一清二楚。掌握了 Standalone你其实已经掌握了 Flink 最核心的运行时架构。接下来你的学习路径可以非常清晰第一深入 Flink 编程 API。去写更多的代码尝试 DataStream API 处理无界数据流尝试 Table API / SQL 用更声明式的方式写业务理解时间Event Time、Processing Time和水位线Watermark这些流处理核心概念。第二探索状态State管理和容错机制。了解 Flink 如何通过 Checkpoint 和 Savepoint 实现“精确一次”处理语义这是它在大数据领域立足的杀手锏。第三连接真实的数据源和汇。尝试从 Kafka 读取实时消息流处理后再写回 Kafka 或者数据库完成一个完整的、贴近生产的实时数据管道。当你觉得在 Standalone 模式下玩得游刃有余了就可以考虑将它“搬迁”到更专业的“办公楼”里也就是YARN 模式或Kubernetes 模式。那时你会发现你的程序代码几乎不需要改动只是提交任务的方式和资源管理的模式变了。你之前学到的关于 JobManager、TaskManager、Slot、并行度的所有知识都完全适用。Standalone 模式带给你的正是这份对原理的透彻理解它能让你在后续面对更复杂环境时依然能够从容地定位问题、优化性能。