从 0 到 1 跑通第一个 Flink ML 示例

简单理解:

  • Flink :负责数据处理引擎------高吞吐、低延迟的流批统一引擎。
  • Flink ML :是在 Flink 之上的机器学习库,提供了算法、Pipeline API 等能力。

使用 Flink ML 有两个典型优势:

  1. 数据就地训练与预测

    你本来就用 Flink 做实时 ETL、流式计算,现在可以在同一套引擎上完成训练和预测,避免频繁导入导出数据。

  2. 天然适配流式场景

    很多业务并不是"离线跑一个模型就完了",而是需要增量更新模型、实时预测、边流式处理边打标签,这类场景 Flink ML 非常适合。

本文的目标是先把"跑通"这件事搞定,后面再谈如何在真实业务中"用好"。

二、环境准备:Java 是前提

Flink 运行在 JVM 上,所以首先要确保本地已经安装了 Java 8 或更高版本

在终端里执行:

bash 复制代码
java -version

正常情况下会输出类似:

text 复制代码
java version "1.8.0_xxx"
Java(TM) SE Runtime Environment (build 1.8.0_xxx)
Java HotSpot(TM) 64-Bit Server VM (build 25.xxx-bxx, mixed mode)

如果提示 command not found 或版本过低,就需要先安装/升级 JDK,这里不展开。

本篇示例使用的是 Flink 1.17(你也可以用其他兼容版本,但建议先按官方 Quick Start 来)。

  1. 从官网或镜像下载 Flink 1.17 安装包(通常是 flink-1.17.x-bin-scala_2.12.tgz 这种名字)。
  2. 在终端中进入下载目录,执行解压命令:
bash 复制代码
tar -xzf flink-*.tgz

解压完成后,你会得到一个类似 flink-1.17.x/ 的目录,这就是本地 Flink 安装目录。

为了后面操作方便,我们通常会配置一个环境变量 FLINK_HOME 指向 Flink 的安装目录。

进入刚才解压出来的目录:

bash 复制代码
cd ${path_to_flink}   # 比如 cd ~/apps/flink-1.17.0
export FLINK_HOME=`pwd`

此时:

  • $FLINK_HOME 就代表 Flink 根目录
  • $FLINK_HOME/bin 下面就是 start-cluster.shflink 等脚本

建议

如果你打算长期使用 Flink,可以把
export FLINK_HOME=/your/flink/path

export PATH=$PATH:$FLINK_HOME/bin

写入 ~/.bashrc~/.zshrc,免得每次都手动 export。

Flink 自身并不自带 Flink ML 的 jar,因此需要我们手动将 Flink ML 的依赖 jar 拷贝到 Flink 的 lib 目录中。

官方 Quick Start 的做法是下载一个类似 apache-flink-ml-*.tar.gz 的压缩包,这里面包含了 Flink ML 的 jar 文件(虽然叫 Python source,但内含 Java jar)。

在终端中执行:

bash 复制代码
tar -xzf apache-flink-ml*.tar.gz

解压后会出现一个类似 apache-flink-ml-*/ 的目录。

继续执行:

bash 复制代码
cp apache-flink-ml-*/deps/lib/* $FLINK_HOME/lib/

这一步的含义是:

把 Flink ML 依赖目录下的所有 jar 文件,复制到 Flink 的 lib 目录里。

为什么要拷到 $FLINK_HOME/lib

因为 Flink 的 Standalone 集群在启动时,会自动加载 lib/ 下的所有 jar 作为全局依赖

这样你提交作业时,只需要提供作业自身的 jar,公共库(如 Flink ML)已经在集群侧可见。

一切准备就绪之后,就可以在本地拉起一个小型的 Flink 集群(实际上是一个 JobManager + 若干 TaskManager)。

在终端执行:

bash 复制代码
$FLINK_HOME/bin/start-cluster.sh

如果成功,你会看到类似:

text 复制代码
Starting cluster.
Starting standalonesession daemon on host ...
Starting taskexecutor daemon on host ...

接着,在浏览器中访问:

text 复制代码
http://localhost:8081

如果看到 Flink 的 Web UI 控制台,说明集群已经成功启动,可以接受作业了。

在 Web UI 中你可以看到:

  • Overview:集群概况
  • Running Jobs:正在运行的作业
  • TaskManagers:工作节点信息等

Flink ML 官方提供了一些示例作业,我们可以先跑一个最经典的 KMeansExample

在终端执行:

bash 复制代码
$FLINK_HOME/bin/flink run \
  -c org.apache.flink.ml.examples.clustering.KMeansExample \
  $FLINK_HOME/lib/flink-ml-examples*.jar

这条命令可以拆解一下理解:

  • $FLINK_HOME/bin/flink run:使用 Flink 提交一个作业

  • -c org.apache.flink.ml.examples.clustering.KMeansExample

    • 指定 main class(作业入口类)
  • $FLINK_HOME/lib/flink-ml-examples*.jar

    • 指定示例 jar 的路径(通常在 Flink ML 的 examples 模块里)

如果命令执行后没有报错,可以回到 Flink Web UI,在 Jobs 页面就能看到这个示例作业的运行记录。

八、示例输出解析:KMeans 把点分成了两簇

示例作业执行成功后,你会在终端看到类似输出:

text 复制代码
Features: [9.0, 0.0]    Cluster ID: 1
Features: [0.3, 0.0]    Cluster ID: 0
Features: [0.0, 0.3]    Cluster ID: 0
Features: [9.6, 0.0]    Cluster ID: 1
Features: [0.0, 0.0]    Cluster ID: 0
Features: [9.0, 0.6]    Cluster ID: 1

这些内容大致含义是:

  • Features :样本的特征向量,这里是二维点 [x, y]
  • Cluster ID:KMeans 训练的结果,将这些点分配到不同的聚类中(例如 0、1)

从数据上可以看出:

  • [0.3, 0.0]、[0.0, 0.3]、[0.0, 0.0] 都被归为 Cluster ID: 0

    ------这一簇大概是"靠近原点的一堆点"

  • [9.0, 0.0]、[9.6, 0.0]、[9.0, 0.6] 都被归为 Cluster ID: 1

    ------这一簇则是"靠近 x=9 左右的一堆点"

也就是说,示例里构造了一些二维数据点,然后使用 KMeans 算法将它们自动分成了两类。

Flink ML 完成的工作大致包括:

  1. 定义数据源(这些样本点)
  2. 构建 KMeans 算法的训练 Pipeline
  3. 在 Flink 上执行训练
  4. 使用训练好的模型对样本进行预测
  5. 将「特征向量 + 聚类结果」打印出来

这就是一个完整的"训练 + 预测"的最小闭环,虽然数据很简单,但流程非常典型。

示例作业跑完之后,如果你暂时不再使用 Flink,可以关闭本地集群:

bash 复制代码
$FLINK_HOME/bin/stop-cluster.sh

执行成功后 JobManager 和 TaskManager 进程会退出,Web UI 也会无法访问。

十、常见问题与排查思路(可选阅读)

第一次上手时,可能会遇到一些小坑,这里简单列出一些常见问题和排查方式:

  1. java: command not foundversion 太低

    • 检查是否安装 JDK
    • 确认 JAVA_HOMEPATH 配置正确
  2. start-cluster.sh 报错

    • 查看 $FLINK_HOME/log 下的日志(standalonesession*.logtaskexecutor*.log
    • 检查端口是否被占用(默认 8081)
  3. 执行示例时提示类找不到(ClassNotFound)

    • 确认 flink-ml-examples*.jar 真的在 $FLINK_HOME/lib/
    • 确认 -c org.apache.flink.ml.examples.clustering.KMeansExample 类名拼写无误
  4. Web UI 打不开

    • 检查进程:ps aux | grep flink
    • 检查防火墙设置或端口占用问题
相关推荐
易营宝6 小时前
多语言网站建设避坑指南:既要“数据同步”,又能“按市场个性化”,别踩这 5 个坑
大数据·人工智能
fanstuck6 小时前
从0到提交,如何用 ChatGPT 全流程参与建模比赛的
大数据·数学建模·语言模型·chatgpt·数据挖掘
春日见6 小时前
vscode代码无法跳转
大数据·人工智能·深度学习·elasticsearch·搜索引擎
好家伙VCC7 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
萤丰信息7 小时前
AI 筑基・生态共荣:智慧园区的价值重构与未来新途
大数据·运维·人工智能·科技·智慧城市·智慧园区
前端玖耀里8 小时前
如何使用python的boto库和SES发送电子邮件?
python
serve the people8 小时前
python环境搭建 (十二) pydantic和pydantic-settings类型验证与解析
java·网络·python
小天源8 小时前
Error 1053 Error 1067 服务“启动后立即停止” Java / Python 程序无法后台运行 windows nssm注册器下载与报错处理
开发语言·windows·python·nssm·error 1053·error 1067
喵手9 小时前
Python爬虫实战:HTTP缓存系统深度实战 — ETag、Last-Modified与requests-cache完全指南(附SQLite持久化存储)!
爬虫·python·爬虫实战·http缓存·etag·零基础python爬虫教学·requests-cache
喵手9 小时前
Python爬虫实战:容器化与定时调度实战 - Docker + Cron + 日志轮转 + 失败重试完整方案(附CSV导出 + SQLite持久化存储)!
爬虫·python·爬虫实战·容器化·零基础python爬虫教学·csv导出·定时调度